From a127d6f3cf2741d4dc404959c5481fa61651e133 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Sat, 16 May 2026 00:07:59 +0800 Subject: Refactor general_renderer into granular format-specific features --- CHANGELOG.md | 8 ++- examples/example-general-renderer/Cargo.lock | 85 ---------------------------- examples/example-general-renderer/Cargo.toml | 2 + mingling/Cargo.toml | 33 ++++++++++- mingling/src/example_docs.rs | 2 + mingling/src/features.rs | 24 ++++++++ mingling/src/lib.rs | 12 ++++ mingling/src/setups/general_renderer.rs | 7 +++ mingling_core/Cargo.toml | 13 ++--- mingling_core/src/program/config.rs | 18 ++++++ mingling_core/src/program/exec.rs | 2 + mingling_core/src/renderer/general.rs | 13 +++++ 12 files changed, 123 insertions(+), 96 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7fec970..b61afd0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,13 @@ None #### Optimizings: -None +1. **\[core\]** The core library no longer depends on `thiserror` + +2. **\[mingling\]** Split the monolithic `general_renderer` feature into separate format-specific features: + - `general_renderer` now only includes core serialization support without any specific format + - `general_renderer_full` bundles all available serialization formats + - Individual format features: `json_serde_fmt`, `yaml_serde_fmt`, `toml_serde_fmt`, `ron_serde_fmt` + - A meta feature `all_serde_fmt` enables all format features at once #### Features: diff --git a/examples/example-general-renderer/Cargo.lock b/examples/example-general-renderer/Cargo.lock index 213a0db..0a617d2 100644 --- a/examples/example-general-renderer/Cargo.lock +++ b/examples/example-general-renderer/Cargo.lock @@ -2,15 +2,6 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "bitflags" -version = "2.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" -dependencies = [ - "serde_core", -] - [[package]] name = "equivalent" version = "1.0.2" @@ -75,11 +66,9 @@ version = "0.1.8" dependencies = [ "just_fmt", "once_cell", - "ron", "serde", "serde_json", "serde_yaml", - "toml", ] [[package]] @@ -117,20 +106,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "ron" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4147b952f3f819eca0e99527022f7d6a8d05f111aeb0a62960c74eb283bec8fc" -dependencies = [ - "bitflags", - "once_cell", - "serde", - "serde_derive", - "typeid", - "unicode-ident", -] - [[package]] name = "ryu" version = "1.0.23" @@ -180,15 +155,6 @@ dependencies = [ "zmij", ] -[[package]] -name = "serde_spanned" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" -dependencies = [ - "serde_core", -] - [[package]] name = "serde_yaml" version = "0.9.34+deprecated" @@ -219,51 +185,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "toml" -version = "1.1.2+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" -dependencies = [ - "indexmap", - "serde_core", - "serde_spanned", - "toml_datetime", - "toml_parser", - "toml_writer", - "winnow", -] - -[[package]] -name = "toml_datetime" -version = "1.1.1+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" -dependencies = [ - "serde_core", -] - -[[package]] -name = "toml_parser" -version = "1.1.2+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" -dependencies = [ - "winnow", -] - -[[package]] -name = "toml_writer" -version = "1.1.1+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" - -[[package]] -name = "typeid" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" - [[package]] name = "unicode-ident" version = "1.0.24" @@ -276,12 +197,6 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" -[[package]] -name = "winnow" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ee1708bef14716a11bae175f579062d4554d95be2c6829f518df847b7b3fdd0" - [[package]] name = "zmij" version = "1.0.21" diff --git a/examples/example-general-renderer/Cargo.toml b/examples/example-general-renderer/Cargo.toml index cc5a541..4664e88 100644 --- a/examples/example-general-renderer/Cargo.toml +++ b/examples/example-general-renderer/Cargo.toml @@ -7,5 +7,7 @@ edition = "2024" mingling = { path = "../../mingling", features = [ "parser", "general_renderer", + "json_serde_fmt", + "yaml_serde_fmt", ] } serde = { version = "1", features = ["derive"] } diff --git a/mingling/Cargo.toml b/mingling/Cargo.toml index 311cb97..da85eaf 100644 --- a/mingling/Cargo.toml +++ b/mingling/Cargo.toml @@ -28,14 +28,41 @@ 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"] +comp = ["mingling_core/comp", "mingling_macros/comp"] +parser = ["dep:size"] + general_renderer = [ "mingling_core/general_renderer", "dep:serde", "mingling_macros/general_renderer", + "json_serde_fmt", ] -repl = ["mingling_core/repl", "mingling_macros/repl"] -comp = ["mingling_core/comp", "mingling_macros/comp"] -parser = ["dep:size"] + +general_renderer_empty = [ + "mingling_core/general_renderer", + "dep:serde", + "mingling_macros/general_renderer", +] + +general_renderer_full = [ + "mingling_core/general_renderer", + "dep:serde", + "mingling_macros/general_renderer", + "all_serde_fmt", +] + +all_serde_fmt = [ + "json_serde_fmt", + "yaml_serde_fmt", + "toml_serde_fmt", + "ron_serde_fmt", +] + +json_serde_fmt = ["mingling_core/json_serde_fmt"] +yaml_serde_fmt = ["mingling_core/yaml_serde_fmt"] +toml_serde_fmt = ["mingling_core/toml_serde_fmt"] +ron_serde_fmt = ["mingling_core/ron_serde_fmt"] [dependencies] mingling_core = { path = "../mingling_core", default-features = false } diff --git a/mingling/src/example_docs.rs b/mingling/src/example_docs.rs index ba61f92..d197c6b 100644 --- a/mingling/src/example_docs.rs +++ b/mingling/src/example_docs.rs @@ -445,6 +445,8 @@ pub mod example_exit_code {} /// mingling = { path = "../../mingling", features = [ /// "parser", /// "general_renderer", +/// "json_serde_fmt", +/// "yaml_serde_fmt", /// ] } /// serde = { version = "1", features = ["derive"] } /// ``` diff --git a/mingling/src/features.rs b/mingling/src/features.rs index d75f926..7d78012 100644 --- a/mingling/src/features.rs +++ b/mingling/src/features.rs @@ -51,3 +51,27 @@ pub const MINGLING_PARSER: bool = false; #[cfg(feature = "parser")] pub const MINGLING_PARSER: bool = true; + +#[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; + +#[cfg(not(feature = "toml_serde_fmt"))] +pub const MINGLING_TOML_SERDE_FMT: bool = false; + +#[cfg(feature = "toml_serde_fmt")] +pub const MINGLING_TOML_SERDE_FMT: bool = true; + +#[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; diff --git a/mingling/src/lib.rs b/mingling/src/lib.rs index 6a165b2..4803c23 100644 --- a/mingling/src/lib.rs +++ b/mingling/src/lib.rs @@ -171,6 +171,18 @@ pub mod feature { /// 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; } mod setups; diff --git a/mingling/src/setups/general_renderer.rs b/mingling/src/setups/general_renderer.rs index a1d1f06..81b6cd0 100644 --- a/mingling/src/setups/general_renderer.rs +++ b/mingling/src/setups/general_renderer.rs @@ -31,22 +31,29 @@ impl ProgramSetup for GeneralRendererSetup where C: ProgramCollect, { + #[allow(unused_variables)] fn setup(&mut self, program: &mut Program) { + #[cfg(feature = "json_serde_fmt")] program.global_flag("--json", |p| { p.general_renderer_name = crate::GeneralRendererSetting::Json }); + #[cfg(feature = "json_serde_fmt")] program.global_flag("--json-pretty", |p| { p.general_renderer_name = crate::GeneralRendererSetting::JsonPretty; }); + #[cfg(feature = "yaml_serde_fmt")] program.global_flag("--yaml", |p| { p.general_renderer_name = crate::GeneralRendererSetting::Yaml; }); + #[cfg(feature = "toml_serde_fmt")] program.global_flag("--toml", |p| { p.general_renderer_name = crate::GeneralRendererSetting::Toml; }); + #[cfg(feature = "ron_serde_fmt")] program.global_flag("--ron", |p| { p.general_renderer_name = crate::GeneralRendererSetting::Ron; }); + #[cfg(feature = "ron_serde_fmt")] program.global_flag("--ron-pretty", |p| { p.general_renderer_name = crate::GeneralRendererSetting::RonPretty; }); diff --git a/mingling_core/Cargo.toml b/mingling_core/Cargo.toml index 118813c..84b974b 100644 --- a/mingling_core/Cargo.toml +++ b/mingling_core/Cargo.toml @@ -13,13 +13,12 @@ async = [] builds = ["dep:dirs"] dispatch_tree = [] -general_renderer = [ - "dep:serde", - "dep:ron", - "dep:serde_json", - "dep:serde_yaml", - "dep:toml", -] +general_renderer = ["dep:serde"] +ron_serde_fmt = ["dep:ron"] +json_serde_fmt = ["dep:serde_json"] +yaml_serde_fmt = ["dep:serde_yaml"] +toml_serde_fmt = ["dep:toml"] + repl = [] clap = [] diff --git a/mingling_core/src/program/config.rs b/mingling_core/src/program/config.rs index c3b1b0e..b5b46a0 100644 --- a/mingling_core/src/program/config.rs +++ b/mingling_core/src/program/config.rs @@ -71,16 +71,22 @@ pub enum GeneralRendererSetting { #[default] Disable, /// Render output as compact JSON. + #[cfg(feature = "json_serde_fmt")] Json, /// Render output as pretty-printed JSON. + #[cfg(feature = "json_serde_fmt")] JsonPretty, /// Render output as YAML. + #[cfg(feature = "yaml_serde_fmt")] Yaml, /// Render output as TOML. + #[cfg(feature = "toml_serde_fmt")] Toml, /// Render output as RON. + #[cfg(feature = "ron_serde_fmt")] Ron, /// Render output as pretty-printed RON. + #[cfg(feature = "ron_serde_fmt")] RonPretty, } @@ -91,11 +97,17 @@ impl std::str::FromStr for GeneralRendererSetting { fn from_str(s: &str) -> Result { match just_fmt::kebab_case!(s).as_str() { "disable" => Ok(GeneralRendererSetting::Disable), + #[cfg(feature = "json_serde_fmt")] "json" => Ok(GeneralRendererSetting::Json), + #[cfg(feature = "json_serde_fmt")] "json-pretty" => Ok(GeneralRendererSetting::JsonPretty), + #[cfg(feature = "yaml_serde_fmt")] "yaml" => Ok(GeneralRendererSetting::Yaml), + #[cfg(feature = "toml_serde_fmt")] "toml" => Ok(GeneralRendererSetting::Toml), + #[cfg(feature = "ron_serde_fmt")] "ron" => Ok(GeneralRendererSetting::Ron), + #[cfg(feature = "ron_serde_fmt")] "ron-pretty" => Ok(GeneralRendererSetting::RonPretty), _ => Err(format!("Invalid renderer: '{}'", s)), } @@ -121,11 +133,17 @@ impl std::fmt::Display for GeneralRendererSetting { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { GeneralRendererSetting::Disable => write!(f, "disable"), + #[cfg(feature = "json_serde_fmt")] GeneralRendererSetting::Json => write!(f, "json"), + #[cfg(feature = "json_serde_fmt")] GeneralRendererSetting::JsonPretty => write!(f, "json-pretty"), + #[cfg(feature = "yaml_serde_fmt")] GeneralRendererSetting::Yaml => write!(f, "yaml"), + #[cfg(feature = "toml_serde_fmt")] GeneralRendererSetting::Toml => write!(f, "toml"), + #[cfg(feature = "ron_serde_fmt")] GeneralRendererSetting::Ron => write!(f, "ron"), + #[cfg(feature = "ron_serde_fmt")] GeneralRendererSetting::RonPretty => write!(f, "ron-pretty"), } } diff --git a/mingling_core/src/program/exec.rs b/mingling_core/src/program/exec.rs index c5ba628..7f7aee4 100644 --- a/mingling_core/src/program/exec.rs +++ b/mingling_core/src/program/exec.rs @@ -278,6 +278,7 @@ fn render>(program: &Program, any: AnyOutput) } #[cfg(feature = "general_renderer")] { + #[allow(unreachable_patterns)] match program.general_renderer_name { super::GeneralRendererSetting::Disable => { let mut render_result = RenderResult::default(); @@ -303,6 +304,7 @@ fn render_help>( } #[cfg(feature = "general_renderer")] { + #[allow(unreachable_patterns)] match program.general_renderer_name { super::GeneralRendererSetting::Disable => { let mut render_result = RenderResult::default(); diff --git a/mingling_core/src/renderer/general.rs b/mingling_core/src/renderer/general.rs index 3808e5a..7d07bac 100644 --- a/mingling_core/src/renderer/general.rs +++ b/mingling_core/src/renderer/general.rs @@ -15,6 +15,7 @@ pub struct GeneralRenderer; impl GeneralRenderer { // Renders data in the specified format to the given RenderResult. + #[allow(unused_variables)] pub fn render( data: &T, setting: &GeneralRendererSetting, @@ -22,16 +23,23 @@ impl GeneralRenderer { ) -> Result<(), GeneralRendererSerializeError> { match setting { GeneralRendererSetting::Disable => Ok(()), + #[cfg(feature = "json_serde_fmt")] GeneralRendererSetting::Json => Self::render_to_json(data, r), + #[cfg(feature = "json_serde_fmt")] GeneralRendererSetting::JsonPretty => Self::render_to_json_pretty(data, r), + #[cfg(feature = "yaml_serde_fmt")] GeneralRendererSetting::Yaml => Self::render_to_yaml(data, r), + #[cfg(feature = "toml_serde_fmt")] GeneralRendererSetting::Toml => Self::render_to_toml(data, r), + #[cfg(feature = "ron_serde_fmt")] GeneralRendererSetting::Ron => Self::render_to_ron(data, r), + #[cfg(feature = "ron_serde_fmt")] GeneralRendererSetting::RonPretty => Self::render_to_ron_pretty(data, r), } } /// Serializes data to JSON format and writes it to the render result. + #[cfg(feature = "json_serde_fmt")] pub fn render_to_json( data: &T, r: &mut RenderResult, @@ -43,6 +51,7 @@ impl GeneralRenderer { } /// Serializes data to pretty-printed JSON format and writes it to the render result. + #[cfg(feature = "json_serde_fmt")] pub fn render_to_json_pretty( data: &T, r: &mut RenderResult, @@ -54,6 +63,7 @@ impl GeneralRenderer { } /// Serializes data to RON format and writes it to the render result. + #[cfg(feature = "ron_serde_fmt")] pub fn render_to_ron( data: &T, r: &mut RenderResult, @@ -65,6 +75,7 @@ impl GeneralRenderer { } /// Serializes data to pretty-printed RON format and writes it to the render result. + #[cfg(feature = "ron_serde_fmt")] pub fn render_to_ron_pretty( data: &T, r: &mut RenderResult, @@ -80,6 +91,7 @@ impl GeneralRenderer { } /// Serializes data to TOML format and writes it to the render result. + #[cfg(feature = "toml_serde_fmt")] pub fn render_to_toml( data: &T, r: &mut RenderResult, @@ -91,6 +103,7 @@ impl GeneralRenderer { } /// Serializes data to YAML format and writes it to the render result. + #[cfg(feature = "yaml_serde_fmt")] pub fn render_to_yaml( data: &T, r: &mut RenderResult, -- cgit