aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml1
-rw-r--r--dev_tools/src/bin/ci.rs1
-rw-r--r--dev_tools/src/bin/refresh-feature-mod.rs97
-rw-r--r--examples/example-repl-advanced/Cargo.lock84
-rw-r--r--examples/example-repl-advanced/Cargo.toml11
-rw-r--r--examples/example-repl-advanced/src/main.rs3
-rw-r--r--mingling/Cargo.toml1
-rw-r--r--mingling/src/example_docs.rs24
-rw-r--r--mingling/src/features.rs225
-rw-r--r--mingling/src/features.rs.tmpl15
-rw-r--r--mingling/src/lib.rs39
11 files changed, 422 insertions, 79 deletions
diff --git a/Cargo.toml b/Cargo.toml
index fcddfc6..f5b9a3a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -17,6 +17,7 @@ exclude = [
"examples/example-hook",
"examples/example-implicit-dispatcher",
"examples/example-panic-unwind",
+ "examples/example-repl-advanced",
"examples/example-repl-basic",
"examples/example-resources",
"examples/example-setup",
diff --git a/dev_tools/src/bin/ci.rs b/dev_tools/src/bin/ci.rs
index 554425e..0547c34 100644
--- a/dev_tools/src/bin/ci.rs
+++ b/dev_tools/src/bin/ci.rs
@@ -102,6 +102,7 @@ fn docs_refresh() -> Result<(), i32> {
run_cmd!("cargo run --manifest-path dev_tools/Cargo.toml --bin docs-code-box-fix")?;
run_cmd!("cargo run --manifest-path dev_tools/Cargo.toml --bin docsify-sidebar-gen")?;
run_cmd!("cargo run --manifest-path dev_tools/Cargo.toml --bin refresh-docs")?;
+ run_cmd!("cargo run --manifest-path dev_tools/Cargo.toml --bin refresh-feature-mod")?;
Ok(())
}
diff --git a/dev_tools/src/bin/refresh-feature-mod.rs b/dev_tools/src/bin/refresh-feature-mod.rs
new file mode 100644
index 0000000..6265e15
--- /dev/null
+++ b/dev_tools/src/bin/refresh-feature-mod.rs
@@ -0,0 +1,97 @@
+use std::collections::BTreeSet;
+use std::path::Path;
+
+use just_fmt::snake_case;
+use just_template::{tmpl, Template};
+use tools::println_cargo_style;
+
+const CARGO_TOML_PATH: &str = "./mingling/Cargo.toml";
+const OUTPUT_PATH: &str = "./mingling/src/features.rs";
+
+const TEMPLATE_CONTENT: &str = include_str!("../../../mingling/src/features.rs.tmpl");
+
+fn main() {
+ gen_feature_module();
+}
+
+fn gen_feature_module() {
+ let repo_root = find_git_repo().unwrap();
+
+ let cargo_toml_path = repo_root.join(CARGO_TOML_PATH);
+ let output_path = repo_root.join(OUTPUT_PATH);
+
+ let features = parse_features(&cargo_toml_path);
+
+ let mut template = Template::from(TEMPLATE_CONTENT);
+
+ for feat_name in &features {
+ let feat_const_name = snake_case!(feat_name).to_uppercase();
+
+ tmpl!(template += {
+ features {
+ (
+ feat_name = feat_name,
+ feat_const_name = feat_const_name
+ )
+ }
+ });
+ println_cargo_style!("Refresh: feature `{}`", feat_name);
+ }
+
+ let template_str = template.to_string();
+ let template_str = template_str
+ .lines()
+ .map(|line| line.trim_end())
+ .collect::<Vec<_>>()
+ .join("\n")
+ + "\n";
+ std::fs::write(&output_path, template_str).unwrap();
+
+ println_cargo_style!("Written: features module to {}", OUTPUT_PATH);
+}
+
+/// Parse all feature names from the `[features]` section of a Cargo.toml.
+fn parse_features(cargo_toml_path: &Path) -> Vec<String> {
+ let content = std::fs::read_to_string(cargo_toml_path)
+ .unwrap_or_else(|e| panic!("Failed to read {}: {}", cargo_toml_path.display(), e));
+
+ let cargo_toml: toml::Value = content
+ .parse()
+ .unwrap_or_else(|e| panic!("Failed to parse {}: {}", cargo_toml_path.display(), e));
+
+ let features_table = cargo_toml
+ .get("features")
+ .and_then(|v| v.as_table())
+ .unwrap_or_else(|| {
+ panic!(
+ "No [features] section found in {}",
+ cargo_toml_path.display()
+ )
+ });
+
+ let mut feature_names: BTreeSet<String> = BTreeSet::new();
+ for key in features_table.keys() {
+ feature_names.insert(key.clone());
+ }
+
+ let mut result: Vec<String> = feature_names.into_iter().collect();
+ result.sort();
+ result
+}
+
+fn find_git_repo() -> Option<std::path::PathBuf> {
+ let mut current_dir = std::env::current_dir().ok()?;
+
+ loop {
+ let git_dir = current_dir.join(".git");
+ if git_dir.exists() && git_dir.is_dir() {
+ return Some(current_dir);
+ }
+
+ if !current_dir.pop() {
+ break;
+ }
+ }
+
+ None
+}
diff --git a/examples/example-repl-advanced/Cargo.lock b/examples/example-repl-advanced/Cargo.lock
new file mode 100644
index 0000000..b18899b
--- /dev/null
+++ b/examples/example-repl-advanced/Cargo.lock
@@ -0,0 +1,84 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "example-repl-advanced"
+version = "0.1.0"
+dependencies = [
+ "just_fmt",
+ "mingling",
+]
+
+[[package]]
+name = "just_fmt"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5454cda0d57db59778608d7a47bff5b16c6705598265869fb052b657f66cf05e"
+
+[[package]]
+name = "mingling"
+version = "0.1.9"
+dependencies = [
+ "mingling_core",
+ "mingling_macros",
+ "size",
+]
+
+[[package]]
+name = "mingling_core"
+version = "0.1.9"
+dependencies = [
+ "just_fmt",
+]
+
+[[package]]
+name = "mingling_macros"
+version = "0.1.9"
+dependencies = [
+ "just_fmt",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.106"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.45"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "size"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b6709c7b6754dca1311b3c73e79fcce40dd414c782c66d88e8823030093b02b"
+
+[[package]]
+name = "syn"
+version = "2.0.117"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
diff --git a/examples/example-repl-advanced/Cargo.toml b/examples/example-repl-advanced/Cargo.toml
new file mode 100644
index 0000000..7f89773
--- /dev/null
+++ b/examples/example-repl-advanced/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "example-repl-advanced"
+version = "0.1.0"
+edition = "2024"
+
+[dependencies.mingling]
+path = "../../mingling"
+features = ["repl", "repl_extra", "parser", "extra_macros"]
+
+[dependencies]
+just_fmt = "0.1.2"
diff --git a/examples/example-repl-advanced/src/main.rs b/examples/example-repl-advanced/src/main.rs
new file mode 100644
index 0000000..e7a11a9
--- /dev/null
+++ b/examples/example-repl-advanced/src/main.rs
@@ -0,0 +1,3 @@
+fn main() {
+ println!("Hello, world!");
+}
diff --git a/mingling/Cargo.toml b/mingling/Cargo.toml
index 68a26d4..e0d2f4a 100644
--- a/mingling/Cargo.toml
+++ b/mingling/Cargo.toml
@@ -51,6 +51,7 @@ default = ["mingling_core/default", "mingling_macros/default"]
clap = ["mingling_core/clap", "mingling_macros/clap"]
dispatch_tree = ["mingling_core/dispatch_tree", "mingling_macros/dispatch_tree"]
repl = ["mingling_core/repl", "mingling_macros/repl"]
+repl_extra = ["repl"]
comp = ["mingling_core/comp", "mingling_macros/comp"]
parser = ["dep:size"]
diff --git a/mingling/src/example_docs.rs b/mingling/src/example_docs.rs
index b665485..b46041f 100644
--- a/mingling/src/example_docs.rs
+++ b/mingling/src/example_docs.rs
@@ -1473,6 +1473,30 @@ pub mod example_implicit_dispatcher {}
/// gen_program!();
/// ```
pub mod example_panic_unwind {}
+
+///
+/// Source code (./Cargo.toml)
+/// ```toml
+/// [package]
+/// name = "example-repl-advanced"
+/// version = "0.1.0"
+/// edition = "2024"
+///
+/// [dependencies.mingling]
+/// path = "../../mingling"
+/// features = ["repl", "repl_extra", "parser", "extra_macros"]
+///
+/// [dependencies]
+/// just_fmt = "0.1.2"
+/// ```
+///
+/// Source code (./src/main.rs)
+/// ```ignore
+/// fn main() {
+/// println!("Hello, world!");
+/// }
+/// ```
+pub mod example_repl_advanced {}
/// Example REPL Basic
///
/// > This example demonstrates how to develop a REPL program using the `repl` feature
diff --git a/mingling/src/features.rs b/mingling/src/features.rs
index 7d78012..365724c 100644
--- a/mingling/src/features.rs
+++ b/mingling/src/features.rs
@@ -1,77 +1,220 @@
-#[cfg(not(feature = "nightly"))]
-pub const MINGLING_NIGHTLY: bool = false;
-
-#[cfg(feature = "nightly")]
-pub const MINGLING_NIGHTLY: bool = true;
-
-#[cfg(not(feature = "debug"))]
-pub const MINGLING_DEBUG: bool = false;
-
-#[cfg(feature = "debug")]
-pub const MINGLING_DEBUG: bool = true;
-
+/// Whether the `all_serde_fmt` feature is enabled
+/// Current: `disabled`
+#[cfg(not(feature = "all_serde_fmt"))]
+#[allow(unused)]
+pub const MINGLING_ALL_SERDE_FMT: bool = false;
+
+/// Whether the `all_serde_fmt` feature is enabled
+/// Current: `enabled`
+#[cfg(feature = "all_serde_fmt")]
+#[allow(unused)]
+pub const MINGLING_ALL_SERDE_FMT: bool = true;
+/// Whether the `async` feature is enabled
+/// Current: `disabled`
#[cfg(not(feature = "async"))]
+#[allow(unused)]
pub const MINGLING_ASYNC: bool = false;
+/// Whether the `async` feature is enabled
+/// Current: `enabled`
#[cfg(feature = "async")]
+#[allow(unused)]
pub const MINGLING_ASYNC: bool = true;
-
+/// Whether the `builds` feature is enabled
+/// Current: `disabled`
+#[cfg(not(feature = "builds"))]
+#[allow(unused)]
+pub const MINGLING_BUILDS: bool = false;
+
+/// Whether the `builds` feature is enabled
+/// Current: `enabled`
+#[cfg(feature = "builds")]
+#[allow(unused)]
+pub const MINGLING_BUILDS: bool = true;
+/// Whether the `clap` feature is enabled
+/// Current: `disabled`
#[cfg(not(feature = "clap"))]
+#[allow(unused)]
pub const MINGLING_CLAP: bool = false;
+/// Whether the `clap` feature is enabled
+/// Current: `enabled`
#[cfg(feature = "clap")]
+#[allow(unused)]
pub const MINGLING_CLAP: bool = true;
+/// Whether the `comp` feature is enabled
+/// Current: `disabled`
+#[cfg(not(feature = "comp"))]
+#[allow(unused)]
+pub const MINGLING_COMP: bool = false;
+/// Whether the `comp` feature is enabled
+/// Current: `enabled`
+#[cfg(feature = "comp")]
+#[allow(unused)]
+pub const MINGLING_COMP: bool = true;
+/// Whether the `debug` feature is enabled
+/// Current: `disabled`
+#[cfg(not(feature = "debug"))]
+#[allow(unused)]
+pub const MINGLING_DEBUG: bool = false;
+
+/// Whether the `debug` feature is enabled
+/// Current: `enabled`
+#[cfg(feature = "debug")]
+#[allow(unused)]
+pub const MINGLING_DEBUG: bool = true;
+/// Whether the `default` feature is enabled
+/// Current: `disabled`
+#[cfg(not(feature = "default"))]
+#[allow(unused)]
+pub const MINGLING_DEFAULT: bool = false;
+
+/// Whether the `default` feature is enabled
+/// Current: `enabled`
+#[cfg(feature = "default")]
+#[allow(unused)]
+pub const MINGLING_DEFAULT: bool = true;
+/// Whether the `dispatch_tree` feature is enabled
+/// Current: `disabled`
#[cfg(not(feature = "dispatch_tree"))]
+#[allow(unused)]
pub const MINGLING_DISPATCH_TREE: bool = false;
+/// Whether the `dispatch_tree` feature is enabled
+/// Current: `enabled`
#[cfg(feature = "dispatch_tree")]
+#[allow(unused)]
pub const MINGLING_DISPATCH_TREE: bool = true;
-
+/// Whether the `extra_macros` feature is enabled
+/// Current: `disabled`
+#[cfg(not(feature = "extra_macros"))]
+#[allow(unused)]
+pub const MINGLING_EXTRA_MACROS: bool = false;
+
+/// Whether the `extra_macros` feature is enabled
+/// Current: `enabled`
+#[cfg(feature = "extra_macros")]
+#[allow(unused)]
+pub const MINGLING_EXTRA_MACROS: bool = true;
+/// Whether the `general_renderer` feature is enabled
+/// Current: `disabled`
#[cfg(not(feature = "general_renderer"))]
+#[allow(unused)]
pub const MINGLING_GENERAL_RENDERER: bool = false;
+/// Whether the `general_renderer` feature is enabled
+/// Current: `enabled`
#[cfg(feature = "general_renderer")]
+#[allow(unused)]
pub const MINGLING_GENERAL_RENDERER: bool = true;
+/// Whether the `general_renderer_empty` feature is enabled
+/// Current: `disabled`
+#[cfg(not(feature = "general_renderer_empty"))]
+#[allow(unused)]
+pub const MINGLING_GENERAL_RENDERER_EMPTY: bool = false;
+
+/// Whether the `general_renderer_empty` feature is enabled
+/// Current: `enabled`
+#[cfg(feature = "general_renderer_empty")]
+#[allow(unused)]
+pub const MINGLING_GENERAL_RENDERER_EMPTY: bool = true;
+/// Whether the `general_renderer_full` feature is enabled
+/// Current: `disabled`
+#[cfg(not(feature = "general_renderer_full"))]
+#[allow(unused)]
+pub const MINGLING_GENERAL_RENDERER_FULL: bool = false;
+
+/// Whether the `general_renderer_full` feature is enabled
+/// Current: `enabled`
+#[cfg(feature = "general_renderer_full")]
+#[allow(unused)]
+pub const MINGLING_GENERAL_RENDERER_FULL: bool = true;
+/// Whether the `json_serde_fmt` feature is enabled
+/// Current: `disabled`
+#[cfg(not(feature = "json_serde_fmt"))]
+#[allow(unused)]
+pub const MINGLING_JSON_SERDE_FMT: bool = false;
-#[cfg(not(feature = "repl"))]
-pub const MINGLING_REPL: bool = false;
-
-#[cfg(feature = "repl")]
-pub const MINGLING_REPL: bool = true;
-
-#[cfg(not(feature = "comp"))]
-pub const MINGLING_COMP: bool = false;
-
-#[cfg(feature = "comp")]
-pub const MINGLING_COMP: bool = true;
+/// Whether the `json_serde_fmt` feature is enabled
+/// Current: `enabled`
+#[cfg(feature = "json_serde_fmt")]
+#[allow(unused)]
+pub const MINGLING_JSON_SERDE_FMT: bool = true;
+/// Whether the `nightly` feature is enabled
+/// Current: `disabled`
+#[cfg(not(feature = "nightly"))]
+#[allow(unused)]
+pub const MINGLING_NIGHTLY: bool = false;
+/// Whether the `nightly` feature is enabled
+/// Current: `enabled`
+#[cfg(feature = "nightly")]
+#[allow(unused)]
+pub const MINGLING_NIGHTLY: bool = true;
+/// Whether the `parser` feature is enabled
+/// Current: `disabled`
#[cfg(not(feature = "parser"))]
+#[allow(unused)]
pub const MINGLING_PARSER: bool = false;
+/// Whether the `parser` feature is enabled
+/// Current: `enabled`
#[cfg(feature = "parser")]
+#[allow(unused)]
pub const MINGLING_PARSER: bool = true;
+/// Whether the `repl` feature is enabled
+/// Current: `disabled`
+#[cfg(not(feature = "repl"))]
+#[allow(unused)]
+pub const MINGLING_REPL: bool = false;
-#[cfg(not(feature = "json_serde_fmt"))]
-pub const MINGLING_JSON_SERDE_FMT: bool = false;
-
-#[cfg(feature = "json_serde_fmt")]
-pub const MINGLING_JSON_SERDE_FMT: bool = true;
-
-#[cfg(not(feature = "yaml_serde_fmt"))]
-pub const MINGLING_YAML_SERDE_FMT: bool = false;
-
-#[cfg(feature = "yaml_serde_fmt")]
-pub const MINGLING_YAML_SERDE_FMT: bool = true;
+/// Whether the `repl` feature is enabled
+/// Current: `enabled`
+#[cfg(feature = "repl")]
+#[allow(unused)]
+pub const MINGLING_REPL: bool = true;
+/// Whether the `repl_extra` feature is enabled
+/// Current: `disabled`
+#[cfg(not(feature = "repl_extra"))]
+#[allow(unused)]
+pub const MINGLING_REPL_EXTRA: bool = false;
+
+/// Whether the `repl_extra` feature is enabled
+/// Current: `enabled`
+#[cfg(feature = "repl_extra")]
+#[allow(unused)]
+pub const MINGLING_REPL_EXTRA: bool = true;
+/// Whether the `ron_serde_fmt` feature is enabled
+/// Current: `disabled`
+#[cfg(not(feature = "ron_serde_fmt"))]
+#[allow(unused)]
+pub const MINGLING_RON_SERDE_FMT: bool = false;
+/// Whether the `ron_serde_fmt` feature is enabled
+/// Current: `enabled`
+#[cfg(feature = "ron_serde_fmt")]
+#[allow(unused)]
+pub const MINGLING_RON_SERDE_FMT: bool = true;
+/// Whether the `toml_serde_fmt` feature is enabled
+/// Current: `disabled`
#[cfg(not(feature = "toml_serde_fmt"))]
+#[allow(unused)]
pub const MINGLING_TOML_SERDE_FMT: bool = false;
+/// Whether the `toml_serde_fmt` feature is enabled
+/// Current: `enabled`
#[cfg(feature = "toml_serde_fmt")]
+#[allow(unused)]
pub const MINGLING_TOML_SERDE_FMT: bool = true;
+/// Whether the `yaml_serde_fmt` feature is enabled
+/// Current: `disabled`
+#[cfg(not(feature = "yaml_serde_fmt"))]
+#[allow(unused)]
+pub const MINGLING_YAML_SERDE_FMT: bool = false;
-#[cfg(not(feature = "ron_serde_fmt"))]
-pub const MINGLING_RON_SERDE_FMT: bool = false;
-
-#[cfg(feature = "ron_serde_fmt")]
-pub const MINGLING_RON_SERDE_FMT: bool = true;
+/// Whether the `yaml_serde_fmt` feature is enabled
+/// Current: `enabled`
+#[cfg(feature = "yaml_serde_fmt")]
+#[allow(unused)]
+pub const MINGLING_YAML_SERDE_FMT: bool = true;
diff --git a/mingling/src/features.rs.tmpl b/mingling/src/features.rs.tmpl
new file mode 100644
index 0000000..3447041
--- /dev/null
+++ b/mingling/src/features.rs.tmpl
@@ -0,0 +1,15 @@
+>>>>>>>>>> features
+
+@@@ >>> features
+/// Whether the `<<<feat_name>>>` feature is enabled
+/// Current: `disabled`
+#[cfg(not(feature = "<<<feat_name>>>"))]
+#[allow(unused)]
+pub const MINGLING_<<<feat_const_name>>>: bool = false;
+
+/// Whether the `<<<feat_name>>>` feature is enabled
+/// Current: `enabled`
+#[cfg(feature = "<<<feat_name>>>")]
+#[allow(unused)]
+pub const MINGLING_<<<feat_const_name>>>: bool = true;
+@@@ <<<
diff --git a/mingling/src/lib.rs b/mingling/src/lib.rs
index 83fd64e..ee01fb7 100644
--- a/mingling/src/lib.rs
+++ b/mingling/src/lib.rs
@@ -155,44 +155,7 @@ mod features;
/// They can be used for conditional compilation or runtime branching based on
/// feature availability.
pub mod feature {
- /// Whether the `async` feature is enabled
- pub use crate::features::MINGLING_ASYNC;
-
- /// Whether the `clap` feature is enabled
- pub use crate::features::MINGLING_CLAP;
-
- /// Whether the `comp` feature is enabled
- pub use crate::features::MINGLING_COMP;
-
- /// Whether the `debug` feature is enabled
- pub use crate::features::MINGLING_DEBUG;
-
- /// Whether the `dispatch_tree` feature is enabled
- pub use crate::features::MINGLING_DISPATCH_TREE;
-
- /// Whether the `general_renderer` feature is enabled
- pub use crate::features::MINGLING_GENERAL_RENDERER;
-
- /// Whether the `nightly` feature is enabled
- pub use crate::features::MINGLING_NIGHTLY;
-
- /// Whether the `parser` feature is enabled
- pub use crate::features::MINGLING_PARSER;
-
- /// Whether the `repl` feature is enabled
- pub use crate::features::MINGLING_REPL;
-
- /// Whether the `json_serde_fmt` feature is enabled
- pub use crate::features::MINGLING_JSON_SERDE_FMT;
-
- /// Whether the `ron_serde_fmt` feature is enabled
- pub use crate::features::MINGLING_RON_SERDE_FMT;
-
- /// Whether the `toml_serde_fmt` feature is enabled
- pub use crate::features::MINGLING_TOML_SERDE_FMT;
-
- /// Whether the `yaml_serde_fmt` feature is enabled
- pub use crate::features::MINGLING_YAML_SERDE_FMT;
+ include!("./features.rs");
}
mod setups;