diff options
57 files changed, 535 insertions, 516 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index c1ad00b..8bee517 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,12 +19,12 @@ - **Global resource** (`global_resource.rs`): `GlobalResource` new, Deref, AsRef; three default implementations of `ResourceMarker` - **Lazy resource** (`lazy_resource.rs`): Coverage of all 18+ methods of `LazyRes`, including initialization triggering, get_ref/get_mut/get_clone, into_inner/unwrap, Drop callback, `ResourceMarker` integration - **Error types** (`chain/error.rs`, `program/error.rs`): All Display, Error source, From conversions - - **Configuration structs** (`config.rs`): Default values for `ProgramStdoutSetting`, `ProgramUserContext`; FromStr parsing and Display output of `GeneralRendererSetting` (feature-gated) + - **Configuration structs** (`config.rs`): Default values for `ProgramStdoutSetting`, `ProgramUserContext`; FromStr parsing and Display output of `StructuralRendererSetting` (feature-gated) - **Flag system** (`flag.rs`): Added 8 From conversions, Deref, AsRef for `Flag` - **String wrapper** (`string_vec.rs`): 6 From conversions, Deref, Into\<Vec\> - **Render result** (`render_result.rs`): print/println/clear/is_empty, Write trait, Display, Deref, From conversions - - **Render error** (`general/error.rs`): Construction, From, Deref, Into\<String\> - - **General renderer** (`general.rs`): Rendering in Disable/JSON/YAML/TOML/RON formats (feature-gated) + - **Render error** (`structural/error.rs`): Construction, From, Deref, Into\<String\> + - **Structural renderer** (`structural.rs`): Rendering in Disable/JSON/YAML/TOML/RON formats (feature-gated) - **Completion suggestions** (`suggest.rs`): All construction, access, modification, sorting, and conversion methods for `Suggest` and `SuggestItem` - **Shell context** (`shell_ctx.rs`): Added `filling_argument`, `filling_argument_first`, `typing_argument`, `strip_typed_argument`, `get_typed_arguments` - **Hook system** (`hook.rs`): `ProgramHook::empty` and all 8 builder methods @@ -37,10 +37,10 @@ - `test-basic`: Basic type tests with default features (Node, Flag, RenderResult, NextProcess, StringVec) - `test-comp`: ShellContext, Suggest, SuggestItem, is_completing with `comp + builds` features - - `test-general-renderer`: GeneralRenderer output in various formats with `general_renderer_full + parser` features + - `test-structural-renderer`: StructuralRenderer output in various formats with `structural_renderer_full + parser` features - `test-repl`: ResREPL and basic types with `repl + extra_macros` features - `test-dispatch-tree`: Basic types with `dispatch_tree` feature - - `test-all`: Comprehensive testing with all feature combinations (ShellContext, Suggest, ResREPL, GeneralRenderer, Hooks, basic types, etc.) + - `test-all`: Comprehensive testing with all feature combinations (ShellContext, Suggest, ResREPL, StructuralRenderer, Hooks, basic types, etc.) These crates are located in `mingling_core/tests/test-*/`, each marked as an independent workspace via `[workspace]`, isolated from the main workspace. @@ -264,9 +264,28 @@ The following explicit syntaxes are **removed**: --- -1. **\[core\]** Changed the signature of `ProgramSetup::setup` from `fn setup(&mut self, program: &mut Program<C>) -> S` to `fn setup(self, program: &mut Program<C>)`, consuming `self` instead of taking a mutable reference. Correspondingly, `Program::with_setup` now accepts `S` by value (`&mut self, setup: S`) instead of by mutable reference (`&mut self, setup: &mut S`). - -2. **\[core\]** Consolidated resource naming for `ExitCode` and `REPL`: +1. **\[core\]** **\[structural_renderer\]** Renamed the `general_renderer` feature to `structural_renderer`. All associated types, structs, and APIs have been renamed accordingly: + + - Feature flag: `general_renderer` → `structural_renderer` + - Setup struct: `GeneralRendererSetup` → `StructuralRendererSetup` + - Simple setup struct: `GeneralRendererSimpleSetup` → `StructuralRendererSimpleSetup` + - Renderer type: `GeneralRenderer` → `StructuralRenderer` + - Setting enum: `GeneralRendererSetting` → `StructuralRendererSetting` + - Error type: `GeneralRendererSerializeError` → `StructuralRendererSerializeError` + - Field name: `program.general_renderer_name` → `program.structural_renderer_name` + - Trait method: `ProgramCollect::general_render()` → `ProgramCollect::structural_render()` + - Internal module: `mingling_core::renderer::general` → `mingling::renderer::structural` + - Internal static: `GENERAL_RENDERERS` → `STRUCTURAL_RENDERERS` + - Feature gate attributes: `#[cfg(feature = "general_renderer")]` → `#[cfg(feature = "structural_renderer")]` + - Sub-features: `general_renderer_empty` → `structural_renderer_empty`, `general_renderer_full` → `structural_renderer_full` + - Runtime feature constant: `MINGLING_GENERAL_RENDERER` → `MINGLING_STRUCTURAL_RENDERER` (and similarly for `_EMPTY` and `_FULL`) + - Derive macro feature gate: `#[cfg(feature = "general_renderer")]` on `#[derive(StructuralData)]` and `#[derive(GrouppedSerialize)]` → `#[cfg(feature = "structural_renderer")]` + - Example project: `example-general-renderer` renamed to `example-structural-renderer` + - Test crate: `test-general-renderer` renamed to `test-structural-renderer` + +2. **\[core\]** Changed the signature of `ProgramSetup::setup` from `fn setup(&mut self, program: &mut Program<C>) -> S` to `fn setup(self, program: &mut Program<C>)`, consuming `self` instead of taking a mutable reference. Correspondingly, `Program::with_setup` now accepts `S` by value (`&mut self, setup: S`) instead of by mutable reference (`&mut self, setup: &mut S`). + +3. **\[core\]** Consolidated resource naming for `ExitCode` and `REPL`: - Renamed `ExitCode` to `ResExitCode` and moved `ResREPL` from the `mingling` root to `mingling::res::ResREPL` (the `mingling::ResREPL` re-export is removed). - This aligns with the naming convention where resources are prefixed with `Res`. - The corresponding setup `ExitCodeSetup` and resource injection remain unchanged. @@ -279,7 +298,7 @@ use mingling::{res::ExitCode, REPL}; use mingling::{res::ResExitCode, res::ResREPL}; ``` -3. **\[core\]** **\[macros\]** Migrated `to_chain()` and `to_render()` methods from being generated individually per type by `#[derive(Groupped)]` and `pack!` macros, to being provided as default trait methods on the `Groupped` trait itself. +4. **\[core\]** **\[macros\]** Migrated `to_chain()` and `to_render()` methods from being generated individually per type by `#[derive(Groupped)]` and `pack!` macros, to being provided as default trait methods on the `Groupped` trait itself. Previously, each packed or derived type had its own inherent `to_chain()` and `to_render()` methods generated by the macros. Now, these methods are defined on the `Groupped<Group>` trait with default implementations, making them available to all types that implement the trait without redundant code generation. @@ -301,7 +320,7 @@ use mingling::{res::ResExitCode, res::ResREPL}; Removed the per-type inherent method generation from both `groupped.rs` and `pack.rs` in `mingling_macros`. -4. **\[macros\]** Changed the `route!()` macro's error branch from `return e` to `return ::mingling::Groupped::to_chain(e)`, so that the error type no longer needs to be pre-converted to `ChainProcess` via `.to_chain()` or `.to_render()`. The macro now accepts any type implementing `Groupped` in the error position and automatically converts it. +5. **\[macros\]** Changed the `route!()` macro's error branch from `return e` to `return ::mingling::Groupped::to_chain(e)`, so that the error type no longer needs to be pre-converted to `ChainProcess` via `.to_chain()` or `.to_render()`. The macro now accepts any type implementing `Groupped` in the error position and automatically converts it. ```rust // Before @@ -311,7 +330,7 @@ let value = route!(prev.pick_or_route((), Error::default().to_chain()).unpack()) let value = route!(prev.pick_or_route((), Error::default()).unpack()); ``` -5. **\[core\]** **\[hook\]** Refactored the hook system to use structured info types and return `ProgramControls<C>` instead of raw values. +6. **\[core\]** **\[hook\]** Refactored the hook system to use structured info types and return `ProgramControls<C>` instead of raw values. The hook system has been redesigned for better type safety, extensibility, and control flow management: @@ -351,15 +370,15 @@ let value = route!(prev.pick_or_route((), Error::default()).unpack()); - **Examples and internal callers updated** throughout the codebase to use the new hook API patterns. -6. **\[core\]** **\[general_renderer\]** Added the `pack_err_structural!`, `pack_structural!`, and `group_structural!` macros for creating types that support structured output (JSON/YAML/TOML/RON). These are like `pack_err!`, `pack!`, and `group!` respectively, but also mark the type with the `StructuralData` trait, enabling the `GeneralRenderer` to serialize them. +7. **\[core\]** **\[structural_renderer\]** Added the `pack_err_structural!`, `pack_structural!`, and `group_structural!` macros for creating types that support structured output (JSON/YAML/TOML/RON). These are like `pack_err!`, `pack!`, and `group!` respectively, but also mark the type with the `StructuralData` trait, enabling the `StructuralRenderer` to serialize them. -7. **\[core\]** **\[general_renderer\]** Added the `StructuralData` derive macro and sealed trait, decoupling structured output from `Groupped`. Previously, under the `general_renderer` feature, all `pack!` and `pack_err!` types automatically derived `Serialize`. Now, structured output is an opt-in property controlled by `StructuralData`: - - `pack!` / `pack_err!` / `group!` no longer derive `Serialize` even when `general_renderer` is enabled. +8. **\[core\]** **\[structural_renderer\]** Added the `StructuralData` derive macro and sealed trait, decoupling structured output from `Groupped`. Previously, under the `structural_renderer` feature, all `pack!` and `pack_err!` types automatically derived `Serialize`. Now, structured output is an opt-in property controlled by `StructuralData`: + - `pack!` / `pack_err!` / `group!` no longer derive `Serialize` even when `structural_renderer` is enabled. - To enable structured output, use `pack_structural!` / `pack_err_structural!` / `group_structural!` or the `#[derive(StructuralData)]` marker. - The `Groupped` trait no longer requires `Serialize` bounds, and `AnyOutput::new` no longer requires `Serialize`. - - `GeneralRenderer::render` now accepts `T: StructuralData + Send` instead of `T: Serialize + Send`, and the individual format methods (`render_to_json`, etc.) are now private. + - `StructuralRenderer::render` now accepts `T: StructuralData + Send` instead of `T: Serialize + Send`, and the individual format methods (`render_to_json`, etc.) are now private. -8. **\[core\]** **\[general_renderer\]** Added `mingling::__private::StructuralDataSealed` and `mingling::__private::StructuralData` (re-exported from `mingling_core::renderer::general::structural_data`) to support the sealed trait pattern. The `StructuralData` trait is only implementable via the derive macro or the `_structural` macro variants. +9. **\[core\]** **\[structural_renderer\]** Added `mingling::__private::StructuralDataSealed` and `mingling::__private::StructuralData` (re-exported from `mingling_core::renderer::structural::structural_data`) to support the sealed trait pattern. The `StructuralData` trait is only implementable via the derive macro or the `_structural` macro variants. ### Release 0.1.9 (2026-05-29) @@ -48,8 +48,8 @@ 4. **Lightning-Fast Subcommand Dispatch**: With the `dispatch_tree` feature, Mingling hardens the subcommand structure into a prefix tree at **compile time**, enabling blazing-fast subcommand lookup. See examples: [Example](https://github.com/mingling-rs/mingling/blob/main/examples/example-dispatch-tree/src/main.rs) 5. **Lightweight Dependencies, On-Demand Importing**: Minimal core dependencies keep builds fast; enhanced features are imported on demand through fine-grained feature flags. -6. **Structured Output**: Enabling the `general_renderer` feature adds support for flags like `--json` and `--yaml`, providing structured output capabilities. - See examples: [Example](https://github.com/mingling-rs/mingling/blob/main/examples/example-general-renderer/src/main.rs) +6. **Structured Output**: Enabling the `structural_renderer` feature adds support for flags like `--json` and `--yaml`, providing structured output capabilities. + See examples: [Example](https://github.com/mingling-rs/mingling/blob/main/examples/example-structural-renderer/src/main.rs) <h1 align="center"> ✍️ Writing with Mingling ✍️ @@ -658,16 +658,16 @@ fn main() { --- -### 13. General Renderer — Structured Output (JSON/YAML) +### 13. Structural Renderer — Structured Output (JSON/YAML) -With the `general_renderer` feature, users can add `--json` or `--yaml` flags to get structured output instead of human-readable text. +With the `structural_renderer` feature, users can add `--json` or `--yaml` flags to get structured output instead of human-readable text. ```rust -// Features: ["general_renderer", "parser"] +// Features: ["structural_renderer", "parser"] // Dependencies: // serde = "1" -use mingling::{prelude::*, setup::GeneralRendererSetup}; +use mingling::{prelude::*, setup::StructuralRendererSetup}; use mingling::Groupped; use mingling::StructuralData; use serde::Serialize; @@ -693,7 +693,7 @@ fn render_info_result(info: ResultInfo) { fn main() { let mut program = ThisProgram::new(); - program.with_setup(GeneralRendererSetup); // enables --json / --yaml + program.with_setup(StructuralRendererSetup); // enables --json / --yaml program.with_dispatcher(CMDRender); let _ = program.exec(); } @@ -848,7 +848,7 @@ Then check out: </h1> - [ ] Milestone.1 "MVP" - - [x] \[[0.1.4](https://docs.rs/mingling/0.1.4/mingling/)\] \[`core`\] \[`general_renderer`\] **Mingling** can render data into serializable formats via `--json` and `--yaml` flags + - [x] \[[0.1.4](https://docs.rs/mingling/0.1.4/mingling/)\] \[`core`\] \[`structural_renderer`\] **Mingling** can render data into serializable formats via `--json` and `--yaml` flags - [x] \[[0.1.5](https://docs.rs/mingling/0.1.5/mingling/)\] \[`core`\] \[`comp`\] **Mingling** can dynamically invoke itself to provide completions for shells like `bash`, `zsh`, `fish`, and `pwsh` - [x] \[[0.1.6](https://docs.rs/mingling/0.1.6/mingling/)\] \[`core`\] \[`comp`\] **Mingling** can gather more context for smarter completions - [x] \[[0.1.7](https://docs.rs/mingling/0.1.7/mingling/)\] \[`clap`\] Provides a **Clap** compatibility layer, allowing **Mingling** to reuse its powerful parsing capabilities diff --git a/dev_tools/scripts/doc.ps1 b/dev_tools/scripts/doc.ps1 index 20b2173..987f0de 100755 --- a/dev_tools/scripts/doc.ps1 +++ b/dev_tools/scripts/doc.ps1 @@ -1 +1 @@ -cargo doc --workspace --no-deps --features builds,general_renderer,repl,comp,parser,clap,extra_macros --open +cargo doc --workspace --no-deps --features builds,structural_renderer,repl,comp,parser,clap,extra_macros --open diff --git a/dev_tools/scripts/doc.sh b/dev_tools/scripts/doc.sh index 9e67961..5e8a311 100755 --- a/dev_tools/scripts/doc.sh +++ b/dev_tools/scripts/doc.sh @@ -1,3 +1,3 @@ #!/bin/bash -cargo doc --workspace --no-deps --features builds,general_renderer,repl,comp,parser,clap,extra_macros --open +cargo doc --workspace --no-deps --features builds,structural_renderer,repl,comp,parser,clap,extra_macros --open diff --git a/docs/_zh_CN/pages/other/features.md b/docs/_zh_CN/pages/other/features.md index 558720c..cadffec 100644 --- a/docs/_zh_CN/pages/other/features.md +++ b/docs/_zh_CN/pages/other/features.md @@ -7,7 +7,7 @@ **介绍:** -为 `general_renderer` 启用所有序列化格式(JSON、RON、TOML、YAML)的 serde 格式化支持。 +为 `structural_renderer` 启用所有序列化格式(JSON、RON、TOML、YAML)的 serde 格式化支持。 开启此特性将自动启用 `json_serde_fmt`、`ron_serde_fmt`、`toml_serde_fmt`、`yaml_serde_fmt` 四个子特性。 @@ -208,7 +208,7 @@ pack_err!(ErrorNotDir = PathBuf); </details> -## 特性 `general_renderer` +## 特性 `structural_renderer` **介绍:** @@ -216,15 +216,15 @@ pack_err!(ErrorNotDir = PathBuf); 开启后,用户可以通过 `--json` 或 `--yaml` 等标志获取结构化输出。 -详见 [示例](https://mingling-rs.github.io/mingling/docs/example-viewer.html?name=example-general-renderer) +详见 [示例](https://mingling-rs.github.io/mingling/docs/example-viewer.html?name=example-structural-renderer) -## 特性 `general_renderer_empty` +## 特性 `structural_renderer_empty` **介绍:** 启用通用渲染器的空实现版本,适用于不需要实际渲染功能的场景。此特性不启用任何 serde 格式化后端。 -## 特性 `general_renderer_full` +## 特性 `structural_renderer_full` **介绍:** diff --git a/docs/_zh_CN/pages/other/naming_rule.md b/docs/_zh_CN/pages/other/naming_rule.md index 18ebf3f..264cffd 100644 --- a/docs/_zh_CN/pages/other/naming_rule.md +++ b/docs/_zh_CN/pages/other/naming_rule.md @@ -36,7 +36,7 @@ Res + 名称 | 示例 | 说明 | | ---------------------- | ---------------------------------------------- | | `BasicSetup` | 基础初始化(`--quiet`、`--help`、`--confirm`) | -| `GeneralRendererSetup` | 通用渲染器初始化(`--json`、`--yaml` 等) | +| `StructuralRendererSetup` | 通用渲染器初始化(`--json`、`--yaml` 等) | ### 分发器 diff --git a/docs/example-pages/examples.json b/docs/example-pages/examples.json index 4d7c494..f3484f3 100644 --- a/docs/example-pages/examples.json +++ b/docs/example-pages/examples.json @@ -148,22 +148,6 @@ ] }, { - "id": "example-general-renderer", - "name": "General Renderer", - "icon": "📤", - "category": "output", - "desc": "Demonstrates how to render structured output in JSON or YAML using `GeneralRendererSetup` and the `general_renderer` feature.\n", - "tags": [ - "general_renderer", - "--json", - "--yaml" - ], - "files": [ - "src/main.rs", - "Cargo.toml" - ] - }, - { "id": "example-help", "name": "Help", "icon": "💡", @@ -239,11 +223,11 @@ "name": "Pack an Error", "icon": "🛑", "category": "macros", - "desc": "Demonstrates how to use the `pack_err!` macro to define error types with automatic `name` field (snake_case at compile time) and optional `info` field. Also shows `--json` serialization when `general_renderer` is enabled.\n", + "desc": "Demonstrates how to use the `pack_err!` macro to define error types with automatic `name` field (snake_case at compile time) and optional `info` field. Also shows `--json` serialization when `structural_renderer` is enabled.\n", "tags": [ "pack_err!", "extra_macros", - "general_renderer", + "structural_renderer", "--json" ], "files": [ @@ -310,6 +294,22 @@ ] }, { + "id": "example-structural-renderer", + "name": "structural renderer", + "icon": "📤", + "category": "output", + "desc": "Demonstrates how to render structured output in JSON or YAML using `StructuralRendererSetup` and the `structural_renderer` feature.\n", + "tags": [ + "structural_renderer", + "--json", + "--yaml" + ], + "files": [ + "src/main.rs", + "Cargo.toml" + ] + }, + { "id": "example-unit-test", "name": "Unit Test", "icon": "🧪", diff --git a/docs/pages/other/features.md b/docs/pages/other/features.md index 5ee0497..ea5fc93 100644 --- a/docs/pages/other/features.md +++ b/docs/pages/other/features.md @@ -7,7 +7,7 @@ **Description:** -Enables serde formatting support for all serialization formats (JSON, RON, TOML, YAML) in `general_renderer`. +Enables serde formatting support for all serialization formats (JSON, RON, TOML, YAML) in `structural_renderer`. Enabling this feature will automatically enable the four sub-features: `json_serde_fmt`, `ron_serde_fmt`, `toml_serde_fmt`, `yaml_serde_fmt`. @@ -208,27 +208,27 @@ pack_err!(ErrorNotDir = PathBuf); </details> -## Feature `general_renderer` +## Feature `structural_renderer` **Description:** -Enables the general renderer, providing basic content rendering capabilities. Enabling this feature will automatically enable `json_serde_fmt`. +Enables the structural renderer, providing basic content rendering capabilities. Enabling this feature will automatically enable `json_serde_fmt`. When enabled, users can get structured output via flags like `--json` or `--yaml`. -See [example](https://mingling-rs.github.io/mingling/docs/example-viewer.html?name=example-general-renderer) +See [example](https://mingling-rs.github.io/mingling/docs/example-viewer.html?name=example-structural-renderer) -## Feature `general_renderer_empty` +## Feature `structural_renderer_empty` **Description:** -Enables an empty implementation of the general renderer, suitable for scenarios where no actual rendering is needed. This feature does not enable any serde formatting backend. +Enables an empty implementation of the structural renderer, suitable for scenarios where no actual rendering is needed. This feature does not enable any serde formatting backend. -## Feature `general_renderer_full` +## Feature `structural_renderer_full` **Description:** -Enables the full implementation of the general renderer, including all rendering capabilities and serialization format support. Enabling this feature will automatically enable `all_serde_fmt`. +Enables the full implementation of the structural renderer, including all rendering capabilities and serialization format support. Enabling this feature will automatically enable `all_serde_fmt`. ## Feature `json_serde_fmt` diff --git a/docs/pages/other/naming_rule.md b/docs/pages/other/naming_rule.md index 9443481..4f4efe8 100644 --- a/docs/pages/other/naming_rule.md +++ b/docs/pages/other/naming_rule.md @@ -36,7 +36,7 @@ Name + Setup | Example | Description | | ---------------------- | ---------------------------------------------------------- | | `BasicSetup` | Basic initialization (`--quiet`, `--help`, `--confirm`) | -| `GeneralRendererSetup` | General renderer initialization (`--json`, `--yaml`, etc.) | +| `StructuralRendererSetup` | structural renderer initialization (`--json`, `--yaml`, etc.) | ### Dispatcher diff --git a/examples/example-general-renderer/page.toml b/examples/example-general-renderer/page.toml deleted file mode 100644 index 1d3e4b1..0000000 --- a/examples/example-general-renderer/page.toml +++ /dev/null @@ -1,10 +0,0 @@ -[example] -id = "example-general-renderer" -name = "General Renderer" -icon = "📤" -category = "output" -desc = """ -Demonstrates how to render structured output in JSON or YAML using `GeneralRendererSetup` and the `general_renderer` feature. -""" -tags = ["general_renderer", "--json", "--yaml"] -files = ["src/main.rs", "Cargo.toml"] diff --git a/examples/example-pack-err/Cargo.toml b/examples/example-pack-err/Cargo.toml index 883fc89..5d61319 100644 --- a/examples/example-pack-err/Cargo.toml +++ b/examples/example-pack-err/Cargo.toml @@ -9,7 +9,7 @@ serde = { version = "1.0.228", features = ["derive"] } [dependencies.mingling] path = "../../mingling" features = [ - "general_renderer", + "structural_renderer", "extra_macros", ] diff --git a/examples/example-pack-err/page.toml b/examples/example-pack-err/page.toml index 255bbdd..37f2c31 100644 --- a/examples/example-pack-err/page.toml +++ b/examples/example-pack-err/page.toml @@ -4,7 +4,7 @@ name = "Pack an Error" icon = "🛑" category = "macros" desc = """ -Demonstrates how to use the `pack_err!` macro to define error types with automatic `name` field (snake_case at compile time) and optional `info` field. Also shows `--json` serialization when `general_renderer` is enabled. +Demonstrates how to use the `pack_err!` macro to define error types with automatic `name` field (snake_case at compile time) and optional `info` field. Also shows `--json` serialization when `structural_renderer` is enabled. """ -tags = ["pack_err!", "extra_macros", "general_renderer", "--json"] +tags = ["pack_err!", "extra_macros", "structural_renderer", "--json"] files = ["src/main.rs", "Cargo.toml"] diff --git a/examples/example-pack-err/src/main.rs b/examples/example-pack-err/src/main.rs index f859fae..8716333 100644 --- a/examples/example-pack-err/src/main.rs +++ b/examples/example-pack-err/src/main.rs @@ -2,7 +2,7 @@ //! //! > This example demonstrates how to use the `pack_err!` macro to define error types //! > with automatic `name` field (set to snake_case at compile time) and optional `info` field. -//! > Also demonstrates `--json` serialization when `general_renderer` is enabled. +//! > Also demonstrates `--json` serialization when `structural_renderer` is enabled. //! //! Run: //! ```bash @@ -27,7 +27,7 @@ //! ``` use mingling::prelude::*; -use mingling::setup::GeneralRendererSetup; +use mingling::setup::StructuralRendererSetup; use std::path::PathBuf; dispatcher!("find", CMDFind => EntryFind); @@ -45,7 +45,7 @@ dispatcher!("find-structural", CMDFindStructural => EntryFindStructural); // The typed form additionally generates `pub fn new(info)`. // name = "error_not_dir" // -// When `general_renderer` is enabled, the struct also gets +// When `structural_renderer` is enabled, the struct also gets // `#[derive(serde::Serialize)]` for --json / --yaml output. // --------- IMPORTANT --------- @@ -132,8 +132,8 @@ gen_program!(); fn main() { let mut program = ThisProgram::new(); - // Add GeneralRendererSetup to support --json / --yaml flags - program.with_setup(GeneralRendererSetup); + // Add StructuralRendererSetup to support --json / --yaml flags + program.with_setup(StructuralRendererSetup); program.with_dispatcher(CMDFind); program.with_dispatcher(CMDFindStructural); let _ = program.exec(); diff --git a/examples/example-general-renderer/Cargo.lock b/examples/example-structural-renderer/Cargo.lock index 0919b7d..cee5ae3 100644 --- a/examples/example-general-renderer/Cargo.lock +++ b/examples/example-structural-renderer/Cargo.lock @@ -3,7 +3,7 @@ version = 4 [[package]] -name = "example-general-renderer" +name = "example-structural-renderer" version = "0.1.0" dependencies = [ "mingling", @@ -24,9 +24,9 @@ checksum = "5454cda0d57db59778608d7a47bff5b16c6705598265869fb052b657f66cf05e" [[package]] name = "memchr" -version = "2.8.0" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" [[package]] name = "mingling" @@ -68,9 +68,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.45" +version = "1.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" dependencies = [ "proc-macro2", ] @@ -126,9 +126,9 @@ checksum = "1b6709c7b6754dca1311b3c73e79fcce40dd414c782c66d88e8823030093b02b" [[package]] name = "syn" -version = "2.0.117" +version = "2.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" dependencies = [ "proc-macro2", "quote", diff --git a/examples/example-general-renderer/Cargo.toml b/examples/example-structural-renderer/Cargo.toml index fd7879b..2090166 100644 --- a/examples/example-general-renderer/Cargo.toml +++ b/examples/example-structural-renderer/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "example-general-renderer" +name = "example-structural-renderer" version = "0.1.0" edition = "2024" @@ -9,7 +9,7 @@ serde = { version = "1.0.228", features = ["derive"] } [dependencies.mingling] path = "../../mingling" features = [ - "general_renderer", + "structural_renderer", "parser", ] diff --git a/examples/example-structural-renderer/page.toml b/examples/example-structural-renderer/page.toml new file mode 100644 index 0000000..0ed7745 --- /dev/null +++ b/examples/example-structural-renderer/page.toml @@ -0,0 +1,10 @@ +[example] +id = "example-structural-renderer" +name = "structural renderer" +icon = "📤" +category = "output" +desc = """ +Demonstrates how to render structured output in JSON or YAML using `StructuralRendererSetup` and the `structural_renderer` feature. +""" +tags = ["structural_renderer", "--json", "--yaml"] +files = ["src/main.rs", "Cargo.toml"] diff --git a/examples/example-general-renderer/src/main.rs b/examples/example-structural-renderer/src/main.rs index 1e02afb..21077e7 100644 --- a/examples/example-general-renderer/src/main.rs +++ b/examples/example-structural-renderer/src/main.rs @@ -1,12 +1,12 @@ -//! Example General Renderer +//! Example structural renderer //! -//! > This example demonstrates how to use the `general_renderer` feature to render data into structures such as json / yaml +//! > This example demonstrates how to use the `structural_renderer` feature to render data into structures such as json / yaml //! //! Run //! ```bash -//! cargo run --manifest-path examples/example-general-renderer/Cargo.toml --quiet -- render Bob 22 -//! cargo run --manifest-path examples/example-general-renderer/Cargo.toml --quiet -- render Bob 22 --json -//! cargo run --manifest-path examples/example-general-renderer/Cargo.toml --quiet -- render Bob 22 --yaml +//! cargo run --manifest-path examples/example-structural-renderer/Cargo.toml --quiet -- render Bob 22 +//! cargo run --manifest-path examples/example-structural-renderer/Cargo.toml --quiet -- render Bob 22 --json +//! cargo run --manifest-path examples/example-structural-renderer/Cargo.toml --quiet -- render Bob 22 --yaml //! ``` //! //! Output: @@ -18,15 +18,15 @@ //! ``` use mingling::prelude::*; -use mingling::{parser::Picker, setup::GeneralRendererSetup, StructuralData, Groupped}; +use mingling::{parser::Picker, setup::StructuralRendererSetup, StructuralData, Groupped}; use serde::Serialize; dispatcher!("render", CMDRender => EntryRender); fn main() { let mut program = ThisProgram::new(); - // Add `GeneralRendererSetup` to receive user input `--json` `--yaml` parameters - program.with_setup(GeneralRendererSetup); + // Add `StructuralRendererSetup` to receive user input `--json` `--yaml` parameters + program.with_setup(StructuralRendererSetup); program.with_dispatcher(CMDRender); let _ = program.exec(); } @@ -62,7 +62,7 @@ fn parse_render(prev: EntryRender) -> Next { Info { name, age }.to_render() } -/// Implement default renderer for when general_renderer is not specified +/// Implement default renderer for when structural_renderer is not specified #[renderer] fn render_info(prev: Info) { r_println!("{} is {} years old", prev.name, prev.age); diff --git a/examples/full-todolist/Cargo.toml b/examples/full-todolist/Cargo.toml index 50b11a5..e10f0e7 100644 --- a/examples/full-todolist/Cargo.toml +++ b/examples/full-todolist/Cargo.toml @@ -12,7 +12,7 @@ path = "../../mingling" features = [ "parser", "extra_macros", - "general_renderer", + "structural_renderer", ] [workspace] diff --git a/examples/full-todolist/src/main.rs b/examples/full-todolist/src/main.rs index 7f958d4..e4c5aa6 100644 --- a/examples/full-todolist/src/main.rs +++ b/examples/full-todolist/src/main.rs @@ -10,7 +10,7 @@ use mingling::{ macros::route, prelude::*, res::ResExitCode, - setup::{ExitCodeSetup, GeneralRendererSetup, HelpFlagSetup}, + setup::{ExitCodeSetup, StructuralRendererSetup, HelpFlagSetup}, LazyInit, LazyRes, }; @@ -49,7 +49,7 @@ fn main() { // Setups program.with_setup(ExitCodeSetup::default()); - program.with_setup(GeneralRendererSetup); + program.with_setup(StructuralRendererSetup); program.with_setup(HelpFlagSetup::new(["--help", "-h"])); // Flags diff --git a/examples/test-examples.toml b/examples/test-examples.toml index 149f2c6..b4cbb6d 100644 --- a/examples/test-examples.toml +++ b/examples/test-examples.toml @@ -138,12 +138,12 @@ command = "lang-select OCaml" expect.exit-code = 0 expect.result = "Selected: OCaml" -[[test.example-general-renderer]] +[[test.example-structural-renderer]] command = "render Bob 22" expect.exit-code = 0 expect.result = "Bob is 22 years old" -[[test.example-general-renderer]] +[[test.example-structural-renderer]] command = "render Bob 22 --json" expect.exit-code = 0 expect.result = "{\"member_name\":\"Bob\",\"member_age\":22}" diff --git a/mingling/Cargo.toml b/mingling/Cargo.toml index 427bed6..0cb211d 100644 --- a/mingling/Cargo.toml +++ b/mingling/Cargo.toml @@ -15,7 +15,7 @@ serde.workspace = true tokio.workspace = true mingling = { path = ".", features = [ "comp", - "general_renderer", + "structural_renderer", "parser", "repl", ] } @@ -23,7 +23,7 @@ mingling = { path = ".", features = [ [package.metadata.docs.rs] features = [ "builds", - "general_renderer", + "structural_renderer", "repl", "comp", "parser", @@ -45,21 +45,21 @@ repl = ["mingling_core/repl", "mingling_macros/repl"] comp = ["mingling_core/comp", "mingling_macros/comp"] parser = ["dep:size"] -general_renderer = [ - "mingling_core/general_renderer", +structural_renderer = [ + "mingling_core/structural_renderer", "dep:serde", - "mingling_macros/general_renderer", + "mingling_macros/structural_renderer", "json_serde_fmt", ] -general_renderer_empty = [ - "mingling_core/general_renderer", +structural_renderer_empty = [ + "mingling_core/structural_renderer", "dep:serde", - "mingling_macros/general_renderer", + "mingling_macros/structural_renderer", ] -general_renderer_full = [ - "general_renderer", +structural_renderer_full = [ + "structural_renderer", "yaml_serde_fmt", "toml_serde_fmt", "ron_serde_fmt", diff --git a/mingling/src/example_docs.rs b/mingling/src/example_docs.rs index 266a449..c492a11 100644 --- a/mingling/src/example_docs.rs +++ b/mingling/src/example_docs.rs @@ -1170,101 +1170,6 @@ pub mod example_error_handling {} /// gen_program!(); /// ``` pub mod example_exitcode {} -/// Example General Renderer -/// -/// > This example demonstrates how to use the `general_renderer` feature to render data into structures such as json / yaml -/// -/// Run -/// ```bash -/// cargo run --manifest-path examples/example-general-renderer/Cargo.toml --quiet -- render Bob 22 -/// cargo run --manifest-path examples/example-general-renderer/Cargo.toml --quiet -- render Bob 22 --json -/// cargo run --manifest-path examples/example-general-renderer/Cargo.toml --quiet -- render Bob 22 --yaml -/// ``` -/// -/// Output: -/// ```plain -/// Bob is 22 years old -/// {"member_name":"Bob","member_age":22} -/// member_name: Bob -/// member_age: 22 -/// ``` -/// -/// Source code (./Cargo.toml) -/// ```toml -/// [package] -/// name = "example-general-renderer" -/// version = "0.1.0" -/// edition = "2024" -/// -/// [dependencies] -/// serde = { version = "1.0.228", features = ["derive"] } -/// -/// [dependencies.mingling] -/// path = "../../mingling" -/// features = [ -/// "general_renderer", -/// "parser", -/// ] -/// -/// [workspace] -/// ``` -/// -/// Source code (./src/main.rs) -/// ```ignore -/// use mingling::prelude::*; -/// use mingling::{parser::Picker, setup::GeneralRendererSetup, StructuralData, Groupped}; -/// use serde::Serialize; -/// -/// dispatcher!("render", CMDRender => EntryRender); -/// -/// fn main() { -/// let mut program = ThisProgram::new(); -/// // Add `GeneralRendererSetup` to receive user input `--json` `--yaml` parameters -/// program.with_setup(GeneralRendererSetup); -/// program.with_dispatcher(CMDRender); -/// let _ = program.exec(); -/// } -/// -/// // --------- IMPORTANT --------- -/// // For beautiful output structure, do not use `pack!` to wrap the types that need to be output. -/// // Instead, manually implement -/// // __________________________________ Mark as structured data so it can be rendered -/// // / ____________________ Implement serde::Serialize -/// // | / _________ Implement mingling::Groupped -/// // | | / to ensure Mingling can recognize the type -/// // vvvvvvvvvvvv vvvvvvvvv vvvvvvvv -/// #[derive(StructuralData, Serialize, Groupped)] -/// struct Info { -/// #[serde(rename = "member_name")] -/// name: String, -/// #[serde(rename = "member_age")] -/// age: i32, -/// } -/// // This will output: {"member_name":"name","member_age":32} structure -/// -/// // If using pack!(Info = (String, i32)); -/// // Output: {"inner":["name", 32]} -/// -/// // --------- IMPORTANT --------- -/// -/// #[chain] -/// fn parse_render(prev: EntryRender) -> Next { -/// let (name, age) = Picker::new(prev.inner) -/// .pick::<String>(()) -/// .pick::<i32>(()) -/// .unpack(); -/// Info { name, age }.to_render() -/// } -/// -/// /// Implement default renderer for when general_renderer is not specified -/// #[renderer] -/// fn render_info(prev: Info) { -/// r_println!("{} is {} years old", prev.name, prev.age); -/// } -/// -/// gen_program!(); -/// ``` -pub mod example_general_renderer {} /// Example Help /// /// > This example demonstrates how to use the `#[help]` macro to generate help information, @@ -1682,7 +1587,7 @@ pub mod example_outside_type {} /// /// > This example demonstrates how to use the `pack_err!` macro to define error types /// > with automatic `name` field (set to snake_case at compile time) and optional `info` field. -/// > Also demonstrates `--json` serialization when `general_renderer` is enabled. +/// > Also demonstrates `--json` serialization when `structural_renderer` is enabled. /// /// Run: /// ```bash @@ -1719,7 +1624,7 @@ pub mod example_outside_type {} /// [dependencies.mingling] /// path = "../../mingling" /// features = [ -/// "general_renderer", +/// "structural_renderer", /// "extra_macros", /// ] /// @@ -1729,7 +1634,7 @@ pub mod example_outside_type {} /// Source code (./src/main.rs) /// ```ignore /// use mingling::prelude::*; -/// use mingling::setup::GeneralRendererSetup; +/// use mingling::setup::StructuralRendererSetup; /// use std::path::PathBuf; /// /// dispatcher!("find", CMDFind => EntryFind); @@ -1747,7 +1652,7 @@ pub mod example_outside_type {} /// // The typed form additionally generates `pub fn new(info)`. /// // name = "error_not_dir" /// // -/// // When `general_renderer` is enabled, the struct also gets +/// // When `structural_renderer` is enabled, the struct also gets /// // `#[derive(serde::Serialize)]` for --json / --yaml output. /// // --------- IMPORTANT --------- /// @@ -1834,8 +1739,8 @@ pub mod example_outside_type {} /// /// fn main() { /// let mut program = ThisProgram::new(); -/// // Add GeneralRendererSetup to support --json / --yaml flags -/// program.with_setup(GeneralRendererSetup); +/// // Add StructuralRendererSetup to support --json / --yaml flags +/// program.with_setup(StructuralRendererSetup); /// program.with_dispatcher(CMDFind); /// program.with_dispatcher(CMDFindStructural); /// let _ = program.exec(); @@ -2256,6 +2161,101 @@ pub mod example_resources {} /// gen_program!(); /// ``` pub mod example_setup {} +/// Example structural renderer +/// +/// > This example demonstrates how to use the `structural_renderer` feature to render data into structures such as json / yaml +/// +/// Run +/// ```bash +/// cargo run --manifest-path examples/example-structural-renderer/Cargo.toml --quiet -- render Bob 22 +/// cargo run --manifest-path examples/example-structural-renderer/Cargo.toml --quiet -- render Bob 22 --json +/// cargo run --manifest-path examples/example-structural-renderer/Cargo.toml --quiet -- render Bob 22 --yaml +/// ``` +/// +/// Output: +/// ```plain +/// Bob is 22 years old +/// {"member_name":"Bob","member_age":22} +/// member_name: Bob +/// member_age: 22 +/// ``` +/// +/// Source code (./Cargo.toml) +/// ```toml +/// [package] +/// name = "example-structural-renderer" +/// version = "0.1.0" +/// edition = "2024" +/// +/// [dependencies] +/// serde = { version = "1.0.228", features = ["derive"] } +/// +/// [dependencies.mingling] +/// path = "../../mingling" +/// features = [ +/// "structural_renderer", +/// "parser", +/// ] +/// +/// [workspace] +/// ``` +/// +/// Source code (./src/main.rs) +/// ```ignore +/// use mingling::prelude::*; +/// use mingling::{parser::Picker, setup::StructuralRendererSetup, StructuralData, Groupped}; +/// use serde::Serialize; +/// +/// dispatcher!("render", CMDRender => EntryRender); +/// +/// fn main() { +/// let mut program = ThisProgram::new(); +/// // Add `StructuralRendererSetup` to receive user input `--json` `--yaml` parameters +/// program.with_setup(StructuralRendererSetup); +/// program.with_dispatcher(CMDRender); +/// let _ = program.exec(); +/// } +/// +/// // --------- IMPORTANT --------- +/// // For beautiful output structure, do not use `pack!` to wrap the types that need to be output. +/// // Instead, manually implement +/// // __________________________________ Mark as structured data so it can be rendered +/// // / ____________________ Implement serde::Serialize +/// // | / _________ Implement mingling::Groupped +/// // | | / to ensure Mingling can recognize the type +/// // vvvvvvvvvvvv vvvvvvvvv vvvvvvvv +/// #[derive(StructuralData, Serialize, Groupped)] +/// struct Info { +/// #[serde(rename = "member_name")] +/// name: String, +/// #[serde(rename = "member_age")] +/// age: i32, +/// } +/// // This will output: {"member_name":"name","member_age":32} structure +/// +/// // If using pack!(Info = (String, i32)); +/// // Output: {"inner":["name", 32]} +/// +/// // --------- IMPORTANT --------- +/// +/// #[chain] +/// fn parse_render(prev: EntryRender) -> Next { +/// let (name, age) = Picker::new(prev.inner) +/// .pick::<String>(()) +/// .pick::<i32>(()) +/// .unpack(); +/// Info { name, age }.to_render() +/// } +/// +/// /// Implement default renderer for when structural_renderer is not specified +/// #[renderer] +/// fn render_info(prev: Info) { +/// r_println!("{} is {} years old", prev.name, prev.age); +/// } +/// +/// gen_program!(); +/// ``` +pub mod example_structural_renderer {} /// Example Unit Test /// /// > This example shows how to write unit tests for Chain and Renderer in Mingling diff --git a/mingling/src/features.rs b/mingling/src/features.rs index ec9c7ad..8f147fb 100644 --- a/mingling/src/features.rs +++ b/mingling/src/features.rs @@ -97,39 +97,6 @@ pub const MINGLING_EXTRA_MACROS: bool = false; #[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"))] @@ -185,6 +152,39 @@ pub const MINGLING_RON_SERDE_FMT: bool = false; #[cfg(feature = "ron_serde_fmt")] #[allow(unused)] pub const MINGLING_RON_SERDE_FMT: bool = true; +/// Whether the `structural_renderer` feature is enabled +/// Current: `disabled` +#[cfg(not(feature = "structural_renderer"))] +#[allow(unused)] +pub const MINGLING_STRUCTURAL_RENDERER: bool = false; + +/// Whether the `structural_renderer` feature is enabled +/// Current: `enabled` +#[cfg(feature = "structural_renderer")] +#[allow(unused)] +pub const MINGLING_STRUCTURAL_RENDERER: bool = true; +/// Whether the `structural_renderer_empty` feature is enabled +/// Current: `disabled` +#[cfg(not(feature = "structural_renderer_empty"))] +#[allow(unused)] +pub const MINGLING_STRUCTURAL_RENDERER_EMPTY: bool = false; + +/// Whether the `structural_renderer_empty` feature is enabled +/// Current: `enabled` +#[cfg(feature = "structural_renderer_empty")] +#[allow(unused)] +pub const MINGLING_STRUCTURAL_RENDERER_EMPTY: bool = true; +/// Whether the `structural_renderer_full` feature is enabled +/// Current: `disabled` +#[cfg(not(feature = "structural_renderer_full"))] +#[allow(unused)] +pub const MINGLING_STRUCTURAL_RENDERER_FULL: bool = false; + +/// Whether the `structural_renderer_full` feature is enabled +/// Current: `enabled` +#[cfg(feature = "structural_renderer_full")] +#[allow(unused)] +pub const MINGLING_STRUCTURAL_RENDERER_FULL: bool = true; /// Whether the `toml_serde_fmt` feature is enabled /// Current: `disabled` #[cfg(not(feature = "toml_serde_fmt"))] diff --git a/mingling/src/lib.rs b/mingling/src/lib.rs index 4c49f15..b021479 100644 --- a/mingling/src/lib.rs +++ b/mingling/src/lib.rs @@ -97,7 +97,7 @@ pub mod macros { #[cfg(feature = "extra_macros")] pub use mingling_macros::group; /// Like `group!` but also marks the type for structured output - #[cfg(all(feature = "general_renderer", feature = "extra_macros"))] + #[cfg(all(feature = "structural_renderer", feature = "extra_macros"))] pub use mingling_macros::group_structural; /// Used to generate a struct implementing the `HelpRequest` trait via a method pub use mingling_macros::help; @@ -106,13 +106,13 @@ pub mod macros { /// Used to create a wrapper type for use with `Chain` and `Renderer` pub use mingling_macros::pack; /// Like `pack!` but also marks the type for structured output - #[cfg(feature = "general_renderer")] + #[cfg(feature = "structural_renderer")] pub use mingling_macros::pack_structural; /// Used to create an error struct with automatic `name` field #[cfg(feature = "extra_macros")] pub use mingling_macros::pack_err; /// Like `pack_err!` but also marks the type for structured output - #[cfg(all(feature = "general_renderer", feature = "extra_macros"))] + #[cfg(all(feature = "structural_renderer", feature = "extra_macros"))] pub use mingling_macros::pack_err_structural; #[cfg(feature = "comp")] #[doc(hidden)] @@ -158,7 +158,7 @@ pub use mingling_macros::EnumTag; pub use mingling_macros::Groupped; /// derive macro `StructuralData` — marks a type as supporting structured output -#[cfg(feature = "general_renderer")] +#[cfg(feature = "structural_renderer")] pub use mingling_macros::StructuralData; /// Example projects for `Mingling`, for learning how to use `Mingling` @@ -214,13 +214,13 @@ pub mod prelude { /// Re-export of the `pack` macro for creating wrapper types. pub use crate::macros::pack; /// Like `pack!` but also marks the type for structured output - #[cfg(feature = "general_renderer")] + #[cfg(feature = "structural_renderer")] pub use mingling_macros::pack_structural; /// Re-export of the `pack_err` macro for creating error types. #[cfg(feature = "extra_macros")] pub use crate::macros::pack_err; /// Like `pack_err!` but also marks the type for structured output - #[cfg(all(feature = "general_renderer", feature = "extra_macros"))] + #[cfg(all(feature = "structural_renderer", feature = "extra_macros"))] pub use mingling_macros::pack_err_structural; /// Re-export of the `r_print` macro for printing within a renderer context. pub use crate::macros::r_print; diff --git a/mingling/src/setups.rs b/mingling/src/setups.rs index b4fad58..5546268 100644 --- a/mingling/src/setups.rs +++ b/mingling/src/setups.rs @@ -4,11 +4,11 @@ pub use basic::*; mod exit_code; pub use exit_code::*; -#[cfg(feature = "general_renderer")] -mod general_renderer; +#[cfg(feature = "structural_renderer")] +mod structural_renderer; -#[cfg(feature = "general_renderer")] -pub use general_renderer::*; +#[cfg(feature = "structural_renderer")] +pub use structural_renderer::*; #[cfg(feature = "repl")] mod repl_basic; diff --git a/mingling/src/setups/general_renderer.rs b/mingling/src/setups/structural_renderer.rs index 88f5bfa..af3ed91 100644 --- a/mingling/src/setups/general_renderer.rs +++ b/mingling/src/setups/structural_renderer.rs @@ -1,22 +1,22 @@ use mingling_core::{Program, ProgramCollect, setup::ProgramSetup}; -/// Sets up the general renderer for the program: +/// Sets up the structural renderer for the program: /// /// - Adds a `--renderer` global argument to specify the renderer type -pub struct GeneralRendererSimpleSetup; +pub struct StructuralRendererSimpleSetup; -impl<C> ProgramSetup<C> for GeneralRendererSimpleSetup +impl<C> ProgramSetup<C> for StructuralRendererSimpleSetup where C: ProgramCollect<Enum = C>, { fn setup(self, program: &mut Program<C>) { program.global_argument("--renderer", |p, renderer| { - p.general_renderer_name = renderer.into(); + p.structural_renderer_name = renderer.into(); }); } } -/// Sets up the general renderer for the program: +/// Sets up the structural renderer for the program: /// /// - Adds global flags to specify the renderer type: /// * `--json` for JSON output @@ -25,9 +25,9 @@ where /// * `--toml` for TOML output /// * `--ron` for RON output /// * `--ron-pretty` for pretty-printed RON output -pub struct GeneralRendererSetup; +pub struct StructuralRendererSetup; -impl<C> ProgramSetup<C> for GeneralRendererSetup +impl<C> ProgramSetup<C> for StructuralRendererSetup where C: ProgramCollect<Enum = C>, { @@ -35,27 +35,27 @@ where fn setup(self, program: &mut Program<C>) { #[cfg(feature = "json_serde_fmt")] program.global_flag("--json", |p| { - p.general_renderer_name = crate::GeneralRendererSetting::Json; + p.structural_renderer_name = crate::StructuralRendererSetting::Json; }); #[cfg(feature = "json_serde_fmt")] program.global_flag("--json-pretty", |p| { - p.general_renderer_name = crate::GeneralRendererSetting::JsonPretty; + p.structural_renderer_name = crate::StructuralRendererSetting::JsonPretty; }); #[cfg(feature = "yaml_serde_fmt")] program.global_flag("--yaml", |p| { - p.general_renderer_name = crate::GeneralRendererSetting::Yaml; + p.structural_renderer_name = crate::StructuralRendererSetting::Yaml; }); #[cfg(feature = "toml_serde_fmt")] program.global_flag("--toml", |p| { - p.general_renderer_name = crate::GeneralRendererSetting::Toml; + p.structural_renderer_name = crate::StructuralRendererSetting::Toml; }); #[cfg(feature = "ron_serde_fmt")] program.global_flag("--ron", |p| { - p.general_renderer_name = crate::GeneralRendererSetting::Ron; + p.structural_renderer_name = crate::StructuralRendererSetting::Ron; }); #[cfg(feature = "ron_serde_fmt")] program.global_flag("--ron-pretty", |p| { - p.general_renderer_name = crate::GeneralRendererSetting::RonPretty; + p.structural_renderer_name = crate::StructuralRendererSetting::RonPretty; }); } } diff --git a/mingling_core/Cargo.toml b/mingling_core/Cargo.toml index 4ce9ecd..b22a630 100644 --- a/mingling_core/Cargo.toml +++ b/mingling_core/Cargo.toml @@ -17,7 +17,7 @@ async = [] builds = [] dispatch_tree = [] -general_renderer = ["dep:serde"] +structural_renderer = ["dep:serde"] ron_serde_fmt = ["dep:ron"] json_serde_fmt = ["dep:serde_json"] yaml_serde_fmt = ["dep:serde_yaml"] @@ -35,7 +35,7 @@ just_fmt.workspace = true # comp just_template = { workspace = true, optional = true } -# general_renderer +# structural_renderer serde = { workspace = true, optional = true } ron = { workspace = true, optional = true } serde_json = { workspace = true, optional = true } diff --git a/mingling_core/src/any.rs b/mingling_core/src/any.rs index ef9f912..ad02b0c 100644 --- a/mingling_core/src/any.rs +++ b/mingling_core/src/any.rs @@ -161,7 +161,7 @@ mod tests { } #[derive(Debug, Clone, PartialEq)] - #[cfg_attr(feature = "general_renderer", derive(serde::Serialize))] + #[cfg_attr(feature = "structural_renderer", derive(serde::Serialize))] struct AlphaData { value: i32, } @@ -173,7 +173,7 @@ mod tests { } #[derive(Debug, Clone, PartialEq)] - #[cfg_attr(feature = "general_renderer", derive(serde::Serialize))] + #[cfg_attr(feature = "structural_renderer", derive(serde::Serialize))] struct BetaData { name: String, } @@ -186,7 +186,7 @@ mod tests { #[derive(Debug, Clone, PartialEq)] #[allow(dead_code)] - #[cfg_attr(feature = "general_renderer", derive(serde::Serialize))] + #[cfg_attr(feature = "structural_renderer", derive(serde::Serialize))] struct GammaData; impl Groupped<MockGroup> for GammaData { @@ -333,9 +333,9 @@ mod tests { assert_eq!(format!("{}", NextProcess::Renderer), "Renderer"); } - // AnyOutput::restore general_renderer feature only + // AnyOutput::restore structural_renderer feature only - #[cfg(feature = "general_renderer")] + #[cfg(feature = "structural_renderer")] #[test] fn test_any_output_restore_success() { use serde::Serialize; @@ -357,7 +357,7 @@ mod tests { assert_eq!(restored, Some(SerData { x: 42 })); } - #[cfg(feature = "general_renderer")] + #[cfg(feature = "structural_renderer")] #[test] fn test_any_output_restore_type_mismatch() { use serde::Serialize; diff --git a/mingling_core/src/any/group.rs b/mingling_core/src/any/group.rs index 07f8400..afe5e3a 100644 --- a/mingling_core/src/any/group.rs +++ b/mingling_core/src/any/group.rs @@ -3,7 +3,7 @@ use crate::{AnyOutput, ChainProcess}; /// Used to mark a type with a unique enum ID, assisting dynamic dispatch /// /// **Note:** Unlike earlier versions, `Groupped` no longer requires `Serialize` -/// even when the `general_renderer` feature is enabled. Structured output is +/// even when the `structural_renderer` feature is enabled. Structured output is /// controlled separately via the [`StructalData`] trait. pub trait Groupped<Group> where diff --git a/mingling_core/src/comp/flags.rs b/mingling_core/src/comp/flags.rs index 424fe8b..9a88d2e 100644 --- a/mingling_core/src/comp/flags.rs +++ b/mingling_core/src/comp/flags.rs @@ -5,7 +5,7 @@ use just_fmt::snake_case; /// This enum defines the supported shell types that can be used for /// generating shell-specific command syntax, scripts, or completions. #[derive(Default, Debug, Clone)] -#[cfg_attr(feature = "general_renderer", derive(serde::Serialize))] +#[cfg_attr(feature = "structural_renderer", derive(serde::Serialize))] pub enum ShellFlag { /// Represents the Bash shell. #[default] diff --git a/mingling_core/src/comp/shell_ctx.rs b/mingling_core/src/comp/shell_ctx.rs index 616eade..cfa4700 100644 --- a/mingling_core/src/comp/shell_ctx.rs +++ b/mingling_core/src/comp/shell_ctx.rs @@ -6,7 +6,7 @@ use crate::{Flag, ShellFlag, Suggest}; /// providing information about the current command line state /// to guide how completions should be generated. #[derive(Default, Debug)] -#[cfg_attr(feature = "general_renderer", derive(serde::Serialize))] +#[cfg_attr(feature = "structural_renderer", derive(serde::Serialize))] pub struct ShellContext { /// The full command line (-f / --command-line) pub command_line: String, diff --git a/mingling_core/src/comp/suggest.rs b/mingling_core/src/comp/suggest.rs index bd5dea6..a81de64 100644 --- a/mingling_core/src/comp/suggest.rs +++ b/mingling_core/src/comp/suggest.rs @@ -5,7 +5,7 @@ use crate::ShellContext; /// A completion suggestion that tells the shell how to perform completion. /// This can be either a set of specific suggestion items or a request for file completion. #[derive(Debug, Default, Clone, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "general_renderer", derive(serde::Serialize))] +#[cfg_attr(feature = "structural_renderer", derive(serde::Serialize))] pub enum Suggest { /// A set of specific suggestion items for the shell to display. Suggest(BTreeSet<SuggestItem>), @@ -78,7 +78,7 @@ impl std::ops::DerefMut for Suggest { /// The first `String` always holds the suggestion text, and the second `String` (if present) /// holds an optional description providing additional context. #[derive(Debug, Clone, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "general_renderer", derive(serde::Serialize))] +#[cfg_attr(feature = "structural_renderer", derive(serde::Serialize))] pub enum SuggestItem { /// A simple suggestion with only the suggestion text. Simple(String), diff --git a/mingling_core/src/lib.rs b/mingling_core/src/lib.rs index 9d0ac2a..ef7d192 100644 --- a/mingling_core/src/lib.rs +++ b/mingling_core/src/lib.rs @@ -19,12 +19,12 @@ pub mod test { pub use crate::tester::*; } -#[cfg(feature = "general_renderer")] -pub use crate::renderer::general::GeneralRenderer; +#[cfg(feature = "structural_renderer")] +pub use crate::renderer::structural::StructuralRenderer; // NOT re-exported at top level: the `StructuralData` trait is sealed and only // accessible through the derive macro. Users who need the trait can access it -// via `mingling::renderer::general::StructuralData` (through the inner alias). +// via `mingling::renderer::structural::StructuralData` (through the inner alias). pub use crate::any::group::*; pub use crate::any::*; @@ -42,8 +42,8 @@ pub mod error { pub use crate::asset::chain::error::*; pub use crate::exec::error::*; pub use crate::program::error::*; - #[cfg(feature = "general_renderer")] - pub use crate::renderer::general::error::*; + #[cfg(feature = "structural_renderer")] + pub use crate::renderer::structural::error::*; } pub use crate::program::*; @@ -83,8 +83,8 @@ pub mod __private { /// Re-export so the derive macro can reference the trait without /// conflicting with the derive macro name at `::mingling::StructuralData`. - #[cfg(feature = "general_renderer")] - pub use crate::renderer::general::structural_data::StructuralData; + #[cfg(feature = "structural_renderer")] + pub use crate::renderer::structural::structural_data::StructuralData; } #[doc(hidden)] diff --git a/mingling_core/src/program.rs b/mingling_core/src/program.rs index e791d86..71d5290 100644 --- a/mingling_core/src/program.rs +++ b/mingling_core/src/program.rs @@ -56,8 +56,8 @@ where pub stdout_setting: ProgramStdoutSetting, pub user_context: ProgramUserContext, - #[cfg(feature = "general_renderer")] - pub general_renderer_name: GeneralRendererSetting, + #[cfg(feature = "structural_renderer")] + pub structural_renderer_name: StructuralRendererSetting, pub(crate) hooks: Vec<ProgramHook<C>>, @@ -99,8 +99,8 @@ where stdout_setting: ProgramStdoutSetting::default(), user_context: ProgramUserContext::default(), - #[cfg(feature = "general_renderer")] - general_renderer_name: GeneralRendererSetting::Disable, + #[cfg(feature = "structural_renderer")] + structural_renderer_name: StructuralRendererSetting::Disable, hooks: Vec::new(), diff --git a/mingling_core/src/program/collection.rs b/mingling_core/src/program/collection.rs index 36a0c94..044379c 100644 --- a/mingling_core/src/program/collection.rs +++ b/mingling_core/src/program/collection.rs @@ -6,8 +6,8 @@ use crate::Dispatcher; use crate::{AnyOutput, ChainProcess, Groupped, RenderResult}; -#[cfg(feature = "general_renderer")] -use crate::{GeneralRendererSetting, error::GeneralRendererSerializeError}; +#[cfg(feature = "structural_renderer")] +use crate::{StructuralRendererSetting, error::StructuralRendererSerializeError}; #[cfg(feature = "comp")] use crate::{ShellContext, Suggest}; @@ -78,15 +78,15 @@ pub trait ProgramCollect { /// Whether the program has a chain that can handle the current [`AnyOutput`](./struct.AnyOutput.html) fn has_chain(any: &AnyOutput<Self::Enum>) -> bool; - /// Perform general rendering and presentation of any type + /// Perform structural rendering and presentation of any type /// /// # Errors /// - /// Returns `Err(GeneralRendererSerializeError)` if serialization of the + /// Returns `Err(StructuralRendererSerializeError)` if serialization of the /// output value fails. - #[cfg(feature = "general_renderer")] - fn general_render( + #[cfg(feature = "structural_renderer")] + fn structural_render( any: AnyOutput<Self::Enum>, - setting: &GeneralRendererSetting, - ) -> Result<RenderResult, GeneralRendererSerializeError>; + setting: &StructuralRendererSetting, + ) -> Result<RenderResult, StructuralRendererSerializeError>; } diff --git a/mingling_core/src/program/collection/mock.rs b/mingling_core/src/program/collection/mock.rs index caef804..b37a709 100644 --- a/mingling_core/src/program/collection/mock.rs +++ b/mingling_core/src/program/collection/mock.rs @@ -6,16 +6,16 @@ use crate::Dispatcher; use crate::{AnyOutput, ChainProcess, Groupped, ProgramCollect, RenderResult}; -#[cfg(feature = "general_renderer")] -use crate::{GeneralRendererSetting, error::GeneralRendererSerializeError}; +#[cfg(feature = "structural_renderer")] +use crate::{StructuralRendererSetting, error::StructuralRendererSerializeError}; #[cfg(feature = "comp")] use crate::{ShellContext, Suggest}; -#[cfg(feature = "general_renderer")] +#[cfg(feature = "structural_renderer")] use serde::Serialize; -#[cfg_attr(feature = "general_renderer", derive(Serialize))] +#[cfg_attr(feature = "structural_renderer", derive(Serialize))] #[allow(unused)] pub enum MockProgramCollect { Foo, @@ -91,11 +91,11 @@ impl ProgramCollect for MockProgramCollect { unreachable!() } - #[cfg(feature = "general_renderer")] - fn general_render( + #[cfg(feature = "structural_renderer")] + fn structural_render( _any: AnyOutput<Self::Enum>, - _setting: &GeneralRendererSetting, - ) -> Result<RenderResult, GeneralRendererSerializeError> { + _setting: &StructuralRendererSetting, + ) -> Result<RenderResult, StructuralRendererSerializeError> { unreachable!() } } diff --git a/mingling_core/src/program/config.rs b/mingling_core/src/program/config.rs index 4e193f2..6d54a4e 100644 --- a/mingling_core/src/program/config.rs +++ b/mingling_core/src/program/config.rs @@ -119,12 +119,12 @@ impl Default for ProgramUserContext { } } -#[cfg(feature = "general_renderer")] +#[cfg(feature = "structural_renderer")] #[derive(Debug, Clone, Default)] -/// Settings for the general renderer output format. +/// Settings for the structural renderer output format. /// /// Controls how structured data (e.g., JSON, YAML, TOML) is rendered to stdout. -pub enum GeneralRendererSetting { +pub enum StructuralRendererSetting { /// Do not render structured output (use default formatting). #[default] Disable, @@ -148,61 +148,61 @@ pub enum GeneralRendererSetting { RonPretty, } -#[cfg(feature = "general_renderer")] -impl std::str::FromStr for GeneralRendererSetting { +#[cfg(feature = "structural_renderer")] +impl std::str::FromStr for StructuralRendererSetting { type Err = String; fn from_str(s: &str) -> Result<Self, Self::Err> { match just_fmt::kebab_case!(s).as_str() { - "disable" => Ok(GeneralRendererSetting::Disable), + "disable" => Ok(StructuralRendererSetting::Disable), #[cfg(feature = "json_serde_fmt")] - "json" => Ok(GeneralRendererSetting::Json), + "json" => Ok(StructuralRendererSetting::Json), #[cfg(feature = "json_serde_fmt")] - "json-pretty" => Ok(GeneralRendererSetting::JsonPretty), + "json-pretty" => Ok(StructuralRendererSetting::JsonPretty), #[cfg(feature = "yaml_serde_fmt")] - "yaml" => Ok(GeneralRendererSetting::Yaml), + "yaml" => Ok(StructuralRendererSetting::Yaml), #[cfg(feature = "toml_serde_fmt")] - "toml" => Ok(GeneralRendererSetting::Toml), + "toml" => Ok(StructuralRendererSetting::Toml), #[cfg(feature = "ron_serde_fmt")] - "ron" => Ok(GeneralRendererSetting::Ron), + "ron" => Ok(StructuralRendererSetting::Ron), #[cfg(feature = "ron_serde_fmt")] - "ron-pretty" => Ok(GeneralRendererSetting::RonPretty), + "ron-pretty" => Ok(StructuralRendererSetting::RonPretty), _ => Err(format!("Invalid renderer: '{s}'")), } } } -#[cfg(feature = "general_renderer")] -impl From<&str> for GeneralRendererSetting { +#[cfg(feature = "structural_renderer")] +impl From<&str> for StructuralRendererSetting { fn from(s: &str) -> Self { - s.parse().unwrap_or(GeneralRendererSetting::Disable) + s.parse().unwrap_or(StructuralRendererSetting::Disable) } } -#[cfg(feature = "general_renderer")] -impl From<String> for GeneralRendererSetting { +#[cfg(feature = "structural_renderer")] +impl From<String> for StructuralRendererSetting { fn from(s: String) -> Self { s.as_str().into() } } -#[cfg(feature = "general_renderer")] -impl std::fmt::Display for GeneralRendererSetting { +#[cfg(feature = "structural_renderer")] +impl std::fmt::Display for StructuralRendererSetting { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - GeneralRendererSetting::Disable => write!(f, "disable"), + StructuralRendererSetting::Disable => write!(f, "disable"), #[cfg(feature = "json_serde_fmt")] - GeneralRendererSetting::Json => write!(f, "json"), + StructuralRendererSetting::Json => write!(f, "json"), #[cfg(feature = "json_serde_fmt")] - GeneralRendererSetting::JsonPretty => write!(f, "json-pretty"), + StructuralRendererSetting::JsonPretty => write!(f, "json-pretty"), #[cfg(feature = "yaml_serde_fmt")] - GeneralRendererSetting::Yaml => write!(f, "yaml"), + StructuralRendererSetting::Yaml => write!(f, "yaml"), #[cfg(feature = "toml_serde_fmt")] - GeneralRendererSetting::Toml => write!(f, "toml"), + StructuralRendererSetting::Toml => write!(f, "toml"), #[cfg(feature = "ron_serde_fmt")] - GeneralRendererSetting::Ron => write!(f, "ron"), + StructuralRendererSetting::Ron => write!(f, "ron"), #[cfg(feature = "ron_serde_fmt")] - GeneralRendererSetting::RonPretty => write!(f, "ron-pretty"), + StructuralRendererSetting::RonPretty => write!(f, "ron-pretty"), } } } @@ -236,113 +236,113 @@ mod tests { assert!(!ctx.assume_yes); } - #[cfg(feature = "general_renderer")] - mod general_renderer_tests { + #[cfg(feature = "structural_renderer")] + mod structural_renderer_tests { use super::*; #[test] fn from_str_disable() { - let val: GeneralRendererSetting = "disable".parse().unwrap(); - assert!(matches!(val, GeneralRendererSetting::Disable)); + let val: StructuralRendererSetting = "disable".parse().unwrap(); + assert!(matches!(val, StructuralRendererSetting::Disable)); } #[cfg(feature = "json_serde_fmt")] #[test] fn from_str_json() { - let val: GeneralRendererSetting = "json".parse().unwrap(); - assert!(matches!(val, GeneralRendererSetting::Json)); + let val: StructuralRendererSetting = "json".parse().unwrap(); + assert!(matches!(val, StructuralRendererSetting::Json)); } #[cfg(feature = "json_serde_fmt")] #[test] fn from_str_json_pretty() { - let val: GeneralRendererSetting = "json-pretty".parse().unwrap(); - assert!(matches!(val, GeneralRendererSetting::JsonPretty)); + let val: StructuralRendererSetting = "json-pretty".parse().unwrap(); + assert!(matches!(val, StructuralRendererSetting::JsonPretty)); } #[cfg(feature = "yaml_serde_fmt")] #[test] fn from_str_yaml() { - let val: GeneralRendererSetting = "yaml".parse().unwrap(); - assert!(matches!(val, GeneralRendererSetting::Yaml)); + let val: StructuralRendererSetting = "yaml".parse().unwrap(); + assert!(matches!(val, StructuralRendererSetting::Yaml)); } #[cfg(feature = "toml_serde_fmt")] #[test] fn from_str_toml() { - let val: GeneralRendererSetting = "toml".parse().unwrap(); - assert!(matches!(val, GeneralRendererSetting::Toml)); + let val: StructuralRendererSetting = "toml".parse().unwrap(); + assert!(matches!(val, StructuralRendererSetting::Toml)); } #[cfg(feature = "ron_serde_fmt")] #[test] fn from_str_ron() { - let val: GeneralRendererSetting = "ron".parse().unwrap(); - assert!(matches!(val, GeneralRendererSetting::Ron)); + let val: StructuralRendererSetting = "ron".parse().unwrap(); + assert!(matches!(val, StructuralRendererSetting::Ron)); } #[cfg(feature = "ron_serde_fmt")] #[test] fn from_str_ron_pretty() { - let val: GeneralRendererSetting = "ron-pretty".parse().unwrap(); - assert!(matches!(val, GeneralRendererSetting::RonPretty)); + let val: StructuralRendererSetting = "ron-pretty".parse().unwrap(); + assert!(matches!(val, StructuralRendererSetting::RonPretty)); } #[test] fn from_str_invalid() { - let res: Result<GeneralRendererSetting, String> = "invalid".parse(); + let res: Result<StructuralRendererSetting, String> = "invalid".parse(); assert!(res.is_err()); } #[test] fn from_str_kebab_case() { - let val: GeneralRendererSetting = "JsonPretty".parse().unwrap(); - assert!(matches!(val, GeneralRendererSetting::JsonPretty)); + let val: StructuralRendererSetting = "JsonPretty".parse().unwrap(); + assert!(matches!(val, StructuralRendererSetting::JsonPretty)); } #[test] fn from_str_case_insensitive() { - let val: GeneralRendererSetting = "JSON".parse().unwrap(); - assert!(matches!(val, GeneralRendererSetting::Json)); + let val: StructuralRendererSetting = "JSON".parse().unwrap(); + assert!(matches!(val, StructuralRendererSetting::Json)); } #[test] fn from_and_str() { - let val = <GeneralRendererSetting as From<&str>>::from("json"); + let val = <StructuralRendererSetting as From<&str>>::from("json"); assert!( - matches!(val, GeneralRendererSetting::Disable) - || matches!(val, GeneralRendererSetting::Json) + matches!(val, StructuralRendererSetting::Disable) + || matches!(val, StructuralRendererSetting::Json) ); - let val = <GeneralRendererSetting as From<&str>>::from("invalid"); - assert!(matches!(val, GeneralRendererSetting::Disable)); + let val = <StructuralRendererSetting as From<&str>>::from("invalid"); + assert!(matches!(val, StructuralRendererSetting::Disable)); } #[test] fn from_string() { - let val = <GeneralRendererSetting as From<String>>::from("json-pretty".to_string()); + let val = <StructuralRendererSetting as From<String>>::from("json-pretty".to_string()); assert!( - matches!(val, GeneralRendererSetting::Disable) - || matches!(val, GeneralRendererSetting::JsonPretty) + matches!(val, StructuralRendererSetting::Disable) + || matches!(val, StructuralRendererSetting::JsonPretty) ); } #[test] fn display_disable() { - assert_eq!(GeneralRendererSetting::Disable.to_string(), "disable"); + assert_eq!(StructuralRendererSetting::Disable.to_string(), "disable"); } #[cfg(feature = "json_serde_fmt")] #[test] fn display_json() { - assert_eq!(GeneralRendererSetting::Json.to_string(), "json"); + assert_eq!(StructuralRendererSetting::Json.to_string(), "json"); } #[cfg(feature = "json_serde_fmt")] #[test] fn display_json_pretty() { assert_eq!( - GeneralRendererSetting::JsonPretty.to_string(), + StructuralRendererSetting::JsonPretty.to_string(), "json-pretty" ); } diff --git a/mingling_core/src/program/exec.rs b/mingling_core/src/program/exec.rs index 1832430..d1983ed 100644 --- a/mingling_core/src/program/exec.rs +++ b/mingling_core/src/program/exec.rs @@ -459,22 +459,22 @@ pub(crate) fn handle_program_control<C: ProgramCollect<Enum = C>>( #[inline] #[allow(unused_variables)] fn render<C: ProgramCollect<Enum = C>>(program: &Program<C>, any: AnyOutput<C>) -> RenderResult { - #[cfg(not(feature = "general_renderer"))] + #[cfg(not(feature = "structural_renderer"))] { let mut render_result = RenderResult::default(); C::render(any, &mut render_result); render_result } - #[cfg(feature = "general_renderer")] + #[cfg(feature = "structural_renderer")] { #[allow(unreachable_patterns)] - match program.general_renderer_name { - super::GeneralRendererSetting::Disable => { + match program.structural_renderer_name { + super::StructuralRendererSetting::Disable => { let mut render_result = RenderResult::default(); C::render(any, &mut render_result); render_result } - _ => C::general_render(any, &program.general_renderer_name).unwrap(), + _ => C::structural_render(any, &program.structural_renderer_name).unwrap(), } } } @@ -485,17 +485,17 @@ fn render_help<C: ProgramCollect<Enum = C>>( program: &Program<C>, entry: AnyOutput<C>, ) -> RenderResult { - #[cfg(not(feature = "general_renderer"))] + #[cfg(not(feature = "structural_renderer"))] { let mut render_result = RenderResult::default(); C::render_help(entry, &mut render_result); render_result } - #[cfg(feature = "general_renderer")] + #[cfg(feature = "structural_renderer")] { #[allow(unreachable_patterns)] - match program.general_renderer_name { - super::GeneralRendererSetting::Disable => { + match program.structural_renderer_name { + super::StructuralRendererSetting::Disable => { let mut render_result = RenderResult::default(); C::render_help(entry, &mut render_result); render_result diff --git a/mingling_core/src/program/hook.rs b/mingling_core/src/program/hook.rs index 7b07d90..cd758ca 100644 --- a/mingling_core/src/program/hook.rs +++ b/mingling_core/src/program/hook.rs @@ -637,7 +637,7 @@ mod tests { use std::sync::atomic::{AtomicBool, Ordering}; #[derive(Debug, Clone, Copy, PartialEq, Eq)] - #[cfg_attr(feature = "general_renderer", derive(serde::Serialize))] + #[cfg_attr(feature = "structural_renderer", derive(serde::Serialize))] enum MockHookEnum { A, B, @@ -701,11 +701,11 @@ mod tests { unreachable!() } - #[cfg(feature = "general_renderer")] - fn general_render( + #[cfg(feature = "structural_renderer")] + fn structural_render( _any: crate::AnyOutput<MockHookEnum>, - _setting: &crate::GeneralRendererSetting, - ) -> Result<crate::RenderResult, crate::error::GeneralRendererSerializeError> { + _setting: &crate::StructuralRendererSetting, + ) -> Result<crate::RenderResult, crate::error::StructuralRendererSerializeError> { unreachable!() } } diff --git a/mingling_core/src/renderer.rs b/mingling_core/src/renderer.rs index 33dd08d..435518d 100644 --- a/mingling_core/src/renderer.rs +++ b/mingling_core/src/renderer.rs @@ -1,3 +1,3 @@ -#[cfg(feature = "general_renderer")] -pub mod general; +#[cfg(feature = "structural_renderer")] +pub mod structural; pub mod render_result; diff --git a/mingling_core/src/renderer/general.rs b/mingling_core/src/renderer/structural.rs index e6da06b..16ce471 100644 --- a/mingling_core/src/renderer/general.rs +++ b/mingling_core/src/renderer/structural.rs @@ -1,5 +1,5 @@ use crate::{ - GeneralRendererSetting, RenderResult, renderer::general::error::GeneralRendererSerializeError, + StructuralRendererSetting, RenderResult, renderer::structural::error::StructuralRendererSerializeError, }; use serde::Serialize; @@ -8,40 +8,40 @@ pub mod structural_data; use structural_data::StructuralData; -/// A general renderer that supports multiple serialization formats. +/// A structural renderer that supports multiple serialization formats. /// -/// The `GeneralRenderer` provides methods to serialize data into various formats +/// The `StructuralRenderer` provides methods to serialize data into various formats /// including JSON, YAML, TOML, and RON, with support for both regular and /// pretty-printed variants. It is designed to work with types that implement /// the [`StructuralData`] trait (which implies `Serialize`). -pub struct GeneralRenderer; +pub struct StructuralRenderer; -impl GeneralRenderer { +impl StructuralRenderer { /// Renders data in the specified format to the given `RenderResult`. /// /// # Errors /// - /// Returns `Err(GeneralRendererSerializeError)` if serialization fails. + /// Returns `Err(StructuralRendererSerializeError)` if serialization fails. #[allow(unused_variables)] pub fn render<T: StructuralData + Send>( data: &T, - setting: &GeneralRendererSetting, + setting: &StructuralRendererSetting, r: &mut RenderResult, - ) -> Result<(), GeneralRendererSerializeError> { + ) -> Result<(), StructuralRendererSerializeError> { match setting { - GeneralRendererSetting::Disable => Ok(()), + StructuralRendererSetting::Disable => Ok(()), #[cfg(feature = "json_serde_fmt")] - GeneralRendererSetting::Json => Self::render_to_json(data, r), + StructuralRendererSetting::Json => Self::render_to_json(data, r), #[cfg(feature = "json_serde_fmt")] - GeneralRendererSetting::JsonPretty => Self::render_to_json_pretty(data, r), + StructuralRendererSetting::JsonPretty => Self::render_to_json_pretty(data, r), #[cfg(feature = "yaml_serde_fmt")] - GeneralRendererSetting::Yaml => Self::render_to_yaml(data, r), + StructuralRendererSetting::Yaml => Self::render_to_yaml(data, r), #[cfg(feature = "toml_serde_fmt")] - GeneralRendererSetting::Toml => Self::render_to_toml(data, r), + StructuralRendererSetting::Toml => Self::render_to_toml(data, r), #[cfg(feature = "ron_serde_fmt")] - GeneralRendererSetting::Ron => Self::render_to_ron(data, r), + StructuralRendererSetting::Ron => Self::render_to_ron(data, r), #[cfg(feature = "ron_serde_fmt")] - GeneralRendererSetting::RonPretty => Self::render_to_ron_pretty(data, r), + StructuralRendererSetting::RonPretty => Self::render_to_ron_pretty(data, r), } } @@ -49,14 +49,14 @@ impl GeneralRenderer { /// /// # Errors /// - /// Returns `Err(GeneralRendererSerializeError)` if serialization fails. + /// Returns `Err(StructuralRendererSerializeError)` if serialization fails. #[cfg(feature = "json_serde_fmt")] fn render_to_json<T: Serialize + Send>( data: &T, r: &mut RenderResult, - ) -> Result<(), GeneralRendererSerializeError> { + ) -> Result<(), StructuralRendererSerializeError> { let json_string = serde_json::to_string(data) - .map_err(|e| GeneralRendererSerializeError::new(e.to_string()))?; + .map_err(|e| StructuralRendererSerializeError::new(e.to_string()))?; r.print(&json_string); Ok(()) } @@ -65,14 +65,14 @@ impl GeneralRenderer { /// /// # Errors /// - /// Returns `Err(GeneralRendererSerializeError)` if serialization fails. + /// Returns `Err(StructuralRendererSerializeError)` if serialization fails. #[cfg(feature = "json_serde_fmt")] fn render_to_json_pretty<T: Serialize + Send>( data: &T, r: &mut RenderResult, - ) -> Result<(), GeneralRendererSerializeError> { + ) -> Result<(), StructuralRendererSerializeError> { let json_string = serde_json::to_string_pretty(data) - .map_err(|e| GeneralRendererSerializeError::new(e.to_string()))?; + .map_err(|e| StructuralRendererSerializeError::new(e.to_string()))?; r.print(&json_string); Ok(()) } @@ -81,14 +81,14 @@ impl GeneralRenderer { /// /// # Errors /// - /// Returns `Err(GeneralRendererSerializeError)` if serialization fails. + /// Returns `Err(StructuralRendererSerializeError)` if serialization fails. #[cfg(feature = "ron_serde_fmt")] fn render_to_ron<T: Serialize + Send>( data: &T, r: &mut RenderResult, - ) -> Result<(), GeneralRendererSerializeError> { + ) -> Result<(), StructuralRendererSerializeError> { let ron_string = ron::ser::to_string(data) - .map_err(|e| GeneralRendererSerializeError::new(e.to_string()))?; + .map_err(|e| StructuralRendererSerializeError::new(e.to_string()))?; r.print(&ron_string); Ok(()) } @@ -97,18 +97,18 @@ impl GeneralRenderer { /// /// # Errors /// - /// Returns `Err(GeneralRendererSerializeError)` if serialization fails. + /// Returns `Err(StructuralRendererSerializeError)` if serialization fails. #[cfg(feature = "ron_serde_fmt")] fn render_to_ron_pretty<T: Serialize + Send>( data: &T, r: &mut RenderResult, - ) -> Result<(), GeneralRendererSerializeError> { + ) -> Result<(), StructuralRendererSerializeError> { let pretty_config = ron::ser::PrettyConfig::new() .new_line("\n") .indentor(" "); let ron_string = ron::ser::to_string_pretty(data, pretty_config) - .map_err(|e| GeneralRendererSerializeError::new(e.to_string()))?; + .map_err(|e| StructuralRendererSerializeError::new(e.to_string()))?; r.print(&ron_string); Ok(()) } @@ -117,14 +117,14 @@ impl GeneralRenderer { /// /// # Errors /// - /// Returns `Err(GeneralRendererSerializeError)` if serialization fails. + /// Returns `Err(StructuralRendererSerializeError)` if serialization fails. #[cfg(feature = "toml_serde_fmt")] fn render_to_toml<T: Serialize + Send>( data: &T, r: &mut RenderResult, - ) -> Result<(), GeneralRendererSerializeError> { + ) -> Result<(), StructuralRendererSerializeError> { let toml_string = - toml::to_string(data).map_err(|e| GeneralRendererSerializeError::new(e.to_string()))?; + toml::to_string(data).map_err(|e| StructuralRendererSerializeError::new(e.to_string()))?; r.print(&toml_string); Ok(()) } @@ -133,14 +133,14 @@ impl GeneralRenderer { /// /// # Errors /// - /// Returns `Err(GeneralRendererSerializeError)` if serialization fails. + /// Returns `Err(StructuralRendererSerializeError)` if serialization fails. #[cfg(feature = "yaml_serde_fmt")] fn render_to_yaml<T: Serialize + Send>( data: &T, r: &mut RenderResult, - ) -> Result<(), GeneralRendererSerializeError> { + ) -> Result<(), StructuralRendererSerializeError> { let yaml_string = serde_yaml::to_string(data) - .map_err(|e| GeneralRendererSerializeError::new(e.to_string()))?; + .map_err(|e| StructuralRendererSerializeError::new(e.to_string()))?; r.print(&yaml_string); Ok(()) } @@ -172,7 +172,7 @@ mod tests { fn test_render_disable_does_nothing() { let mut r = RenderResult::default(); let result = - GeneralRenderer::render(&test_data(), &GeneralRendererSetting::Disable, &mut r); + StructuralRenderer::render(&test_data(), &StructuralRendererSetting::Disable, &mut r); assert!(result.is_ok()); assert!(r.is_empty()); } @@ -182,7 +182,7 @@ mod tests { fn test_render_to_json() { let mut r = RenderResult::default(); let result = - GeneralRenderer::render(&test_data(), &GeneralRendererSetting::Json, &mut r); + StructuralRenderer::render(&test_data(), &StructuralRendererSetting::Json, &mut r); assert!(result.is_ok()); assert!(!r.is_empty()); let output: String = r.into(); @@ -197,7 +197,7 @@ mod tests { fn test_render_to_json_pretty() { let mut r = RenderResult::default(); let result = - GeneralRenderer::render(&test_data(), &GeneralRendererSetting::JsonPretty, &mut r); + StructuralRenderer::render(&test_data(), &StructuralRendererSetting::JsonPretty, &mut r); assert!(result.is_ok()); let output: String = r.into(); // Pretty JSON has newlines @@ -209,7 +209,7 @@ mod tests { fn test_render_to_yaml() { let mut r = RenderResult::default(); let result = - GeneralRenderer::render(&test_data(), &GeneralRendererSetting::Yaml, &mut r); + StructuralRenderer::render(&test_data(), &StructuralRendererSetting::Yaml, &mut r); assert!(result.is_ok()); assert!(!r.is_empty()); } @@ -219,7 +219,7 @@ mod tests { fn test_render_to_toml() { let mut r = RenderResult::default(); let result = - GeneralRenderer::render(&test_data(), &GeneralRendererSetting::Toml, &mut r); + StructuralRenderer::render(&test_data(), &StructuralRendererSetting::Toml, &mut r); assert!(result.is_ok()); assert!(!r.is_empty()); } @@ -229,7 +229,7 @@ mod tests { fn test_render_to_ron() { let mut r = RenderResult::default(); let result = - GeneralRenderer::render(&test_data(), &GeneralRendererSetting::Ron, &mut r); + StructuralRenderer::render(&test_data(), &StructuralRendererSetting::Ron, &mut r); assert!(result.is_ok()); assert!(!r.is_empty()); } @@ -239,7 +239,7 @@ mod tests { fn test_render_to_ron_pretty() { let mut r = RenderResult::default(); let result = - GeneralRenderer::render(&test_data(), &GeneralRendererSetting::RonPretty, &mut r); + StructuralRenderer::render(&test_data(), &StructuralRendererSetting::RonPretty, &mut r); assert!(result.is_ok()); let output: String = r.into(); assert!(output.contains('\n')); @@ -252,7 +252,7 @@ mod tests { // Disable let result = - GeneralRenderer::render(&test_data(), &GeneralRendererSetting::Disable, &mut r); + StructuralRenderer::render(&test_data(), &StructuralRendererSetting::Disable, &mut r); assert!(result.is_ok()); assert!(r.is_empty()); } @@ -261,7 +261,7 @@ mod tests { #[test] fn test_render_dispatches_json() { let mut r = RenderResult::default(); - let result = GeneralRenderer::render(&test_data(), &GeneralRendererSetting::Json, &mut r); + let result = StructuralRenderer::render(&test_data(), &StructuralRendererSetting::Json, &mut r); assert!(result.is_ok()); assert!(!r.is_empty()); } diff --git a/mingling_core/src/renderer/general/error.rs b/mingling_core/src/renderer/structural/error.rs index 07ca92b..a7fbc75 100644 --- a/mingling_core/src/renderer/general/error.rs +++ b/mingling_core/src/renderer/structural/error.rs @@ -1,27 +1,27 @@ -/// Represents an error that occurs during serialization of a general renderer. +/// Represents an error that occurs during serialization of a structural renderer. /// /// This error stores a human-readable message describing what went wrong /// during the serialization process. #[derive(Debug)] -pub struct GeneralRendererSerializeError { +pub struct StructuralRendererSerializeError { /// The underlying error message. error: String, } -impl GeneralRendererSerializeError { +impl StructuralRendererSerializeError { #[must_use] pub fn new(error: String) -> Self { Self { error } } } -impl From<&str> for GeneralRendererSerializeError { +impl From<&str> for StructuralRendererSerializeError { fn from(s: &str) -> Self { Self::new(s.to_string()) } } -impl std::ops::Deref for GeneralRendererSerializeError { +impl std::ops::Deref for StructuralRendererSerializeError { type Target = String; fn deref(&self) -> &Self::Target { @@ -29,8 +29,8 @@ impl std::ops::Deref for GeneralRendererSerializeError { } } -impl From<GeneralRendererSerializeError> for String { - fn from(val: GeneralRendererSerializeError) -> Self { +impl From<StructuralRendererSerializeError> for String { + fn from(val: StructuralRendererSerializeError) -> Self { val.error } } @@ -42,26 +42,26 @@ mod tests { #[test] fn new_creates_error_with_message() { let msg = "serialization failed".to_string(); - let err = GeneralRendererSerializeError::new(msg.clone()); + let err = StructuralRendererSerializeError::new(msg.clone()); assert_eq!(err.error, msg); } #[test] fn from_str_creates_error_from_string_slice() { - let err: GeneralRendererSerializeError = "oops".into(); + let err: StructuralRendererSerializeError = "oops".into(); assert_eq!(err.error, "oops"); } #[test] fn deref_accesses_inner_error_string() { - let err = GeneralRendererSerializeError::new("inner message".to_string()); + let err = StructuralRendererSerializeError::new("inner message".to_string()); let derefed: &String = &err; assert_eq!(derefed, "inner message"); } #[test] fn into_string_extracts_message() { - let err = GeneralRendererSerializeError::new("extract me".to_string()); + let err = StructuralRendererSerializeError::new("extract me".to_string()); let s: String = err.into(); assert_eq!(s, "extract me"); } diff --git a/mingling_core/src/renderer/general/structural_data.rs b/mingling_core/src/renderer/structural/structural_data.rs index ac6363e..1cafac3 100644 --- a/mingling_core/src/renderer/general/structural_data.rs +++ b/mingling_core/src/renderer/structural/structural_data.rs @@ -10,6 +10,6 @@ use serde::Serialize; /// - `group_structural!` /// /// These entry points also register the type in the global `STRUCTURED_TYPES` -/// registry, which is required for the `general_render` match arm to be generated. +/// registry, which is required for the `structural_render` match arm to be generated. #[doc(hidden)] pub trait StructuralData: Serialize + crate::__private::StructuralDataSealed {} diff --git a/mingling_core/tests/test-all/Cargo.toml b/mingling_core/tests/test-all/Cargo.toml index 9eea2de..a63b6e6 100644 --- a/mingling_core/tests/test-all/Cargo.toml +++ b/mingling_core/tests/test-all/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies] mingling = { path = "../../../mingling", features = [ - "general_renderer_full", + "structural_renderer_full", "comp", "builds", "repl", diff --git a/mingling_core/tests/test-all/tests/integration.rs b/mingling_core/tests/test-all/tests/integration.rs index 99910a9..3581702 100644 --- a/mingling_core/tests/test-all/tests/integration.rs +++ b/mingling_core/tests/test-all/tests/integration.rs @@ -1,6 +1,6 @@ use mingling::Flag; -use mingling::GeneralRenderer; -use mingling::GeneralRendererSetting; +use mingling::StructuralRenderer; +use mingling::StructuralRendererSetting; use mingling::MockProgramCollect; use mingling::NextProcess; use mingling::StructuralData; @@ -89,7 +89,7 @@ fn test_render_result_print() { assert_eq!(&*r, "hello"); } -// GeneralRenderer +// StructuralRenderer #[derive(Debug, Clone, PartialEq, Serialize, StructuralData)] struct TestData { @@ -98,25 +98,25 @@ struct TestData { } #[test] -fn test_general_renderer_disable() { +fn test_structural_renderer_disable() { let data = TestData { name: "test".into(), value: 42, }; let mut r = RenderResult::default(); - let result = GeneralRenderer::render(&data, &GeneralRendererSetting::Disable, &mut r); + let result = StructuralRenderer::render(&data, &StructuralRendererSetting::Disable, &mut r); assert!(result.is_ok()); assert!(r.is_empty()); } #[test] -fn test_general_renderer_json() { +fn test_structural_renderer_json() { let data = TestData { name: "test".into(), value: 42, }; let mut r = RenderResult::default(); - let result = GeneralRenderer::render(&data, &GeneralRendererSetting::Json, &mut r); + let result = StructuralRenderer::render(&data, &StructuralRendererSetting::Json, &mut r); assert!(result.is_ok()); assert!(!r.is_empty()); } diff --git a/mingling_core/tests/test-general-renderer/Cargo.lock b/mingling_core/tests/test-structural-renderer/Cargo.lock index 7c4b628..a0f7088 100644 --- a/mingling_core/tests/test-general-renderer/Cargo.lock +++ b/mingling_core/tests/test-structural-renderer/Cargo.lock @@ -210,7 +210,7 @@ dependencies = [ ] [[package]] -name = "test-general-renderer" +name = "test-structural-renderer" version = "0.1.0" dependencies = [ "mingling", diff --git a/mingling_core/tests/test-general-renderer/Cargo.toml b/mingling_core/tests/test-structural-renderer/Cargo.toml index 3d038aa..6ae8fce 100644 --- a/mingling_core/tests/test-general-renderer/Cargo.toml +++ b/mingling_core/tests/test-structural-renderer/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "test-general-renderer" +name = "test-structural-renderer" version = "0.1.0" edition = "2024" publish = false @@ -7,5 +7,5 @@ publish = false [workspace] [dependencies] -mingling = { path = "../../../mingling", features = ["general_renderer_full", "parser"] } +mingling = { path = "../../../mingling", features = ["structural_renderer_full", "parser"] } serde = { version = "1", features = ["derive"] } diff --git a/mingling_core/tests/test-general-renderer/tests/integration.rs b/mingling_core/tests/test-structural-renderer/tests/integration.rs index 2e2472e..3c3c6db 100644 --- a/mingling_core/tests/test-general-renderer/tests/integration.rs +++ b/mingling_core/tests/test-structural-renderer/tests/integration.rs @@ -1,4 +1,4 @@ -use mingling::{GeneralRenderer, GeneralRendererSetting, RenderResult, StructuralData}; +use mingling::{StructuralRenderer, StructuralRendererSetting, RenderResult, StructuralData}; use serde::Serialize; #[derive(Debug, Clone, PartialEq, Serialize, StructuralData)] @@ -17,7 +17,7 @@ fn test_data() -> TestData { #[test] fn test_render_disable() { let mut r = RenderResult::default(); - let result = GeneralRenderer::render(&test_data(), &GeneralRendererSetting::Disable, &mut r); + let result = StructuralRenderer::render(&test_data(), &StructuralRendererSetting::Disable, &mut r); assert!(result.is_ok()); assert!(r.is_empty()); } @@ -25,7 +25,7 @@ fn test_render_disable() { #[test] fn test_render_json() { let mut r = RenderResult::default(); - let result = GeneralRenderer::render(&test_data(), &GeneralRendererSetting::Json, &mut r); + let result = StructuralRenderer::render(&test_data(), &StructuralRendererSetting::Json, &mut r); assert!(result.is_ok()); assert!(!r.is_empty()); let output: String = r.into(); @@ -38,7 +38,7 @@ fn test_render_json() { #[test] fn test_render_yaml() { let mut r = RenderResult::default(); - let result = GeneralRenderer::render(&test_data(), &GeneralRendererSetting::Yaml, &mut r); + let result = StructuralRenderer::render(&test_data(), &StructuralRendererSetting::Yaml, &mut r); assert!(result.is_ok()); assert!(!r.is_empty()); let output: String = r.into(); @@ -51,7 +51,7 @@ fn test_render_yaml() { #[test] fn test_render_toml() { let mut r = RenderResult::default(); - let result = GeneralRenderer::render(&test_data(), &GeneralRendererSetting::Toml, &mut r); + let result = StructuralRenderer::render(&test_data(), &StructuralRendererSetting::Toml, &mut r); assert!(result.is_ok()); assert!(!r.is_empty()); let output: String = r.into(); @@ -64,7 +64,7 @@ fn test_render_toml() { #[test] fn test_render_ron() { let mut r = RenderResult::default(); - let result = GeneralRenderer::render(&test_data(), &GeneralRendererSetting::Ron, &mut r); + let result = StructuralRenderer::render(&test_data(), &StructuralRendererSetting::Ron, &mut r); assert!(result.is_ok()); assert!(!r.is_empty()); let output: String = r.into(); diff --git a/mingling_macros/Cargo.toml b/mingling_macros/Cargo.toml index a5fdabf..db65381 100644 --- a/mingling_macros/Cargo.toml +++ b/mingling_macros/Cargo.toml @@ -21,7 +21,7 @@ async = [] clap = [] comp = [] dispatch_tree = [] -general_renderer = [] +structural_renderer = [] repl = [] extra_macros = [] diff --git a/mingling_macros/src/groupped.rs b/mingling_macros/src/groupped.rs index 1459522..8aee003 100644 --- a/mingling_macros/src/groupped.rs +++ b/mingling_macros/src/groupped.rs @@ -28,7 +28,7 @@ pub fn derive_groupped(input: TokenStream) -> TokenStream { expanded.into() } -#[cfg(feature = "general_renderer")] +#[cfg(feature = "structural_renderer")] pub fn derive_groupped_serialize(input: TokenStream) -> TokenStream { // Parse the input struct/enum let input_parsed = parse_macro_input!(input as DeriveInput); diff --git a/mingling_macros/src/lib.rs b/mingling_macros/src/lib.rs index 27bb80c..ad3b6a9 100644 --- a/mingling_macros/src/lib.rs +++ b/mingling_macros/src/lib.rs @@ -99,7 +99,7 @@ //! | `comp` | [`#[completion]`](attr.completion.html), [`suggest!`], [`suggest_enum!`] | //! | `extra_macros` | [`entry!`], [`empty_result!`], [`route!`], [`#[program_setup]`](attr.program_setup.html) | //! | `dispatch_tree` | `register_dispatcher!` (enables trie-based command dispatch) | -//! | `general_renderer` | Enables JSON/YAML/TOML/RON serialization renderers | +//! | `structural_renderer` | Enables JSON/YAML/TOML/RON serialization renderers | //! | `async` | Enables async `#[chain]` functions | //! | `repl` | Enables REPL execution loop | //! @@ -156,7 +156,7 @@ mod enum_tag; mod group_impl; mod groupped; mod help; -#[cfg(feature = "general_renderer")] +#[cfg(feature = "structural_renderer")] mod structural_data; mod node; mod pack; @@ -182,12 +182,12 @@ pub(crate) fn get_global_set(lock: &OnceLock<Mutex<BTreeSet<String>>>) -> &Mutex pub(crate) type Registry = OnceLock<Mutex<BTreeSet<String>>>; // Global variables -#[cfg(feature = "general_renderer")] -pub(crate) static GENERAL_RENDERERS: Registry = OnceLock::new(); +#[cfg(feature = "structural_renderer")] +pub(crate) static STRUCTURAL_RENDERERS: Registry = OnceLock::new(); /// Types explicitly marked with `#[derive(StructuralData)]` or created via /// `pack_structural!` / `group_structural!`. -#[cfg(feature = "general_renderer")] +#[cfg(feature = "structural_renderer")] pub(crate) static STRUCTURED_TYPES: Registry = OnceLock::new(); #[cfg(feature = "comp")] @@ -293,8 +293,8 @@ pub fn group(input: TokenStream) -> TokenStream { /// group_structural!(IoError = std::io::Error); /// ``` /// -/// Requires the `general_renderer` and `extra_macros` features. -#[cfg(all(feature = "general_renderer", feature = "extra_macros"))] +/// Requires the `structural_renderer` and `extra_macros` features. +#[cfg(all(feature = "structural_renderer", feature = "extra_macros"))] #[proc_macro] pub fn group_structural(input: TokenStream) -> TokenStream { structural_data::group_structural(input) @@ -384,7 +384,7 @@ pub fn node(input: TokenStream) -> TokenStream { /// The struct is also registered via `register_type!` so that `gen_program!` /// can include it in the program enum. /// -/// When the `general_renderer` feature is enabled, the struct also gets +/// When the `structural_renderer` feature is enabled, the struct also gets /// `#[derive(serde::Serialize)]`. #[proc_macro] pub fn pack(input: TokenStream) -> TokenStream { @@ -406,8 +406,8 @@ pub fn pack(input: TokenStream) -> TokenStream { /// impl ::mingling::StructuralData for Info {} /// ``` /// -/// Requires the `general_renderer` feature. -#[cfg(feature = "general_renderer")] +/// Requires the `structural_renderer` feature. +#[cfg(feature = "structural_renderer")] #[proc_macro] pub fn pack_structural(input: TokenStream) -> TokenStream { structural_data::pack_structural(input) @@ -471,7 +471,7 @@ pub fn pack_structural(input: TokenStream) -> TokenStream { /// } /// ``` /// -/// When the `general_renderer` feature is enabled, the struct also gets +/// When the `structural_renderer` feature is enabled, the struct also gets /// `#[derive(serde::Serialize)]`. /// /// This macro is only available with the `extra_macros` feature. @@ -491,8 +491,8 @@ pub fn pack_err(input: TokenStream) -> TokenStream { /// pack_err_structural!(ErrorNotDir = PathBuf); /// ``` /// -/// Requires the `general_renderer` and `extra_macros` features. -#[cfg(all(feature = "general_renderer", feature = "extra_macros"))] +/// Requires the `structural_renderer` and `extra_macros` features. +#[cfg(all(feature = "structural_renderer", feature = "extra_macros"))] #[proc_macro] pub fn pack_err_structural(input: TokenStream) -> TokenStream { pack_err::pack_err_structural(input) @@ -685,7 +685,7 @@ pub fn dispatcher(input: TokenStream) -> TokenStream { /// Unlike `print!`, this macro writes to the in-memory `RenderResult` buffer /// rather than directly to stdout. The buffered output is flushed automatically /// when the renderer returns, allowing the framework to control output timing -/// and capture (e.g., for testing or general rendering to JSON/YAML). +/// and capture (e.g., for testing or structural rendering to JSON/YAML). /// /// This macro requires a mutable reference to a [`RenderResult`] named /// `__renderer_inner_result` to be in scope, which is automatically provided @@ -1068,7 +1068,7 @@ pub fn completion(attr: TokenStream, item: TokenStream) -> TokenStream { /// /// #[program_setup] /// fn configure(program: &mut Program<ThisProgram>) { -/// program.with_setup(GeneralRendererSetup); +/// program.with_setup(StructuralRendererSetup); /// program.user_context.some_flag = true; /// } /// ``` @@ -1387,7 +1387,7 @@ pub fn derive_enum_tag(input: TokenStream) -> TokenStream { /// age: i32, /// } /// ``` -#[cfg(feature = "general_renderer")] +#[cfg(feature = "structural_renderer")] #[proc_macro_derive(StructuralData)] pub fn derive_structural_data(input: TokenStream) -> TokenStream { structural_data::derive_structural_data(input) @@ -1395,10 +1395,10 @@ pub fn derive_structural_data(input: TokenStream) -> TokenStream { /// Derive macro for implementing both `Groupped` and `serde::Serialize` on a struct. /// -/// **This macro is only available with the `general_renderer` feature.** +/// **This macro is only available with the `structural_renderer` feature.** /// /// This is identical to `#[derive(Groupped)]` but also adds `#[derive(serde::Serialize)]` -/// to the struct, which is required for the general renderer to serialize output +/// to the struct, which is required for the structural renderer to serialize output /// to formats like JSON, YAML, TOML, or RON. /// /// # Syntax @@ -1423,7 +1423,7 @@ pub fn derive_structural_data(input: TokenStream) -> TokenStream { /// age: i32, /// } /// ``` -#[cfg(feature = "general_renderer")] +#[cfg(feature = "structural_renderer")] #[proc_macro_derive(GrouppedSerialize, attributes(group))] pub fn derive_groupped_serialize(input: TokenStream) -> TokenStream { groupped::derive_groupped_serialize(input) @@ -1638,8 +1638,8 @@ pub fn register_chain(input: TokenStream) -> TokenStream { /// /// This macro is called internally by `#[renderer]`(macro.renderer.html) and is /// generally not needed in user code. It inserts entries into the global -/// `RENDERERS`, `RENDERERS_EXIST` and (with `general_renderer` feature) -/// `GENERAL_RENDERERS` registries. +/// `RENDERERS`, `RENDERERS_EXIST` and (with `structural_renderer` feature) +/// `STRUCTURAL_RENDERERS` registries. /// /// # Syntax /// @@ -1704,7 +1704,7 @@ pub fn program_fallback_gen(_input: TokenStream) -> TokenStream { /// creates an enum with each type as a variant. /// 2. Generates the `Display` implementation for the enum. /// 3. Generates the `ProgramCollect` implementation that dispatches to all -/// registered renderers, chains, help handlers, completions, and general renderers. +/// registered renderers, chains, help handlers, completions, and structural renderers. /// 4. Adds a `new()` constructor on the enum returning `Program<EnumName>`. /// /// The generated enum's representation type (`#[repr(u8)]`, `#[repr(u16)]`, etc.) @@ -1738,7 +1738,7 @@ pub fn program_fallback_gen(_input: TokenStream) -> TokenStream { /// fn has_renderer(any) -> bool { /* checks renderer registry */ } /// fn has_chain(any) -> bool { /* checks chain registry */ } /// // (with comp feature) fn do_comp(...) -/// // (with general_renderer feature) fn general_render(...) +/// // (with structural_renderer feature) fn structural_render(...) /// } /// /// impl MyProgram { @@ -1781,8 +1781,8 @@ pub fn program_final_gen(_input: TokenStream) -> TokenStream { let renderer_exist = get_global_set(&RENDERERS_EXIST).lock().unwrap().clone(); let chain_exist = get_global_set(&CHAINS_EXIST).lock().unwrap().clone(); - #[cfg(feature = "general_renderer")] - let general_renderers = get_global_set(&GENERAL_RENDERERS).lock().unwrap().clone(); + #[cfg(feature = "structural_renderer")] + let structural_renderers = get_global_set(&STRUCTURAL_RENDERERS).lock().unwrap().clone(); #[cfg(feature = "comp")] let completions = get_global_set(&COMPLETIONS).lock().unwrap().clone(); @@ -1812,27 +1812,27 @@ pub fn program_final_gen(_input: TokenStream) -> TokenStream { .map(|s| syn::parse_str::<proc_macro2::TokenStream>(s).unwrap()) .collect(); - #[cfg(feature = "general_renderer")] - let general_renderer_tokens: Vec<proc_macro2::TokenStream> = general_renderers + #[cfg(feature = "structural_renderer")] + let structural_renderer_tokens: Vec<proc_macro2::TokenStream> = structural_renderers .iter() .map(|s| syn::parse_str::<proc_macro2::TokenStream>(s).unwrap()) .collect(); - #[cfg(feature = "general_renderer")] - let general_render = quote! { - fn general_render( + #[cfg(feature = "structural_renderer")] + let structural_render = quote! { + fn structural_render( any: ::mingling::AnyOutput<Self::Enum>, - setting: &::mingling::GeneralRendererSetting, - ) -> Result<::mingling::RenderResult, ::mingling::error::GeneralRendererSerializeError> { + setting: &::mingling::StructuralRendererSetting, + ) -> Result<::mingling::RenderResult, ::mingling::error::StructuralRendererSerializeError> { match any.member_id { - #(#general_renderer_tokens)* + #(#structural_renderer_tokens)* _ => Ok(::mingling::RenderResult::default()), } } }; - #[cfg(not(feature = "general_renderer"))] - let general_render = quote! {}; + #[cfg(not(feature = "structural_renderer"))] + let structural_render = quote! {}; #[cfg(feature = "dispatch_tree")] let compile_time_dispatchers: Vec<String> = get_global_set(&COMPILE_TIME_DISPATCHERS) @@ -2048,7 +2048,7 @@ pub fn program_final_gen(_input: TokenStream) -> TokenStream { } } #dispatch_tree_nodes - #general_render + #structural_render #comp } @@ -2079,8 +2079,8 @@ pub fn program_final_gen(_input: TokenStream) -> TokenStream { .lock() .unwrap() .clear(); - #[cfg(feature = "general_renderer")] - get_global_set(&GENERAL_RENDERERS).lock().unwrap().clear(); + #[cfg(feature = "structural_renderer")] + get_global_set(&STRUCTURAL_RENDERERS).lock().unwrap().clear(); TokenStream::from(expanded) } diff --git a/mingling_macros/src/pack.rs b/mingling_macros/src/pack.rs index 5a6ccb0..7f05232 100644 --- a/mingling_macros/src/pack.rs +++ b/mingling_macros/src/pack.rs @@ -34,7 +34,7 @@ pub fn pack(input: TokenStream) -> TokenStream { let attrs = pack_input.attrs; // Generate the struct definition - // Note: No longer derives Serialize under general_renderer. + // Note: No longer derives Serialize under structural_renderer. // Use pack_structual! for structured output support. let struct_def = quote! { #(#attrs)* diff --git a/mingling_macros/src/pack_err.rs b/mingling_macros/src/pack_err.rs index 8f147be..3e258b2 100644 --- a/mingling_macros/src/pack_err.rs +++ b/mingling_macros/src/pack_err.rs @@ -69,7 +69,7 @@ pub fn pack_err(input: TokenStream) -> TokenStream { let name_str = type_name.to_string(); let snake_name = to_snake_case(&name_str); - // Note: No longer derives Serialize under general_renderer. + // Note: No longer derives Serialize under structural_renderer. // Use pack_err_structural for structured output support. let derive = quote! { #[derive(::mingling::Groupped)] @@ -102,7 +102,7 @@ pub fn pack_err(input: TokenStream) -> TokenStream { let name_str = type_name.to_string(); let snake_name = to_snake_case(&name_str); - // Note: No longer derives Serialize under general_renderer. + // Note: No longer derives Serialize under structural_renderer. // Use pack_err_structural for structured output support. let derive = quote! { #[derive(::mingling::Groupped)] @@ -152,7 +152,7 @@ pub fn pack_err(input: TokenStream) -> TokenStream { /// impl ::mingling::__private::StructuralDataSealed for ErrorNotFound {} /// impl ::mingling::__private::StructuralData for ErrorNotFound {} /// ``` -#[cfg(feature = "general_renderer")] +#[cfg(feature = "structural_renderer")] pub fn pack_err_structural(input: TokenStream) -> TokenStream { let parsed = parse_macro_input!(input as PackErrInput); diff --git a/mingling_macros/src/renderer.rs b/mingling_macros/src/renderer.rs index 6de3d59..880c50f 100644 --- a/mingling_macros/src/renderer.rs +++ b/mingling_macros/src/renderer.rs @@ -183,9 +183,9 @@ pub fn build_renderer_exist_entry(previous_type: &TypePath) -> proc_macro2::Toke } } -/// Builds the general renderer entry -#[cfg(feature = "general_renderer")] -pub fn build_general_renderer_entry(previous_type: &TypePath) -> proc_macro2::TokenStream { +/// Builds the structural renderer entry +#[cfg(feature = "structural_renderer")] +pub fn build_structural_renderer_entry(previous_type: &TypePath) -> proc_macro2::TokenStream { let enum_variant = &previous_type.path.segments.last().unwrap().ident; quote! { Self::#enum_variant => { @@ -193,7 +193,7 @@ pub fn build_general_renderer_entry(previous_type: &TypePath) -> proc_macro2::To // and `AnyOutput::new` ensures the type implements serde::Serialize let raw = unsafe { any.restore::<#previous_type>().unwrap_unchecked() }; let mut __renderer_inner_result = ::mingling::RenderResult::default(); - ::mingling::GeneralRenderer::render(&raw, setting, &mut __renderer_inner_result)?; + ::mingling::StructuralRenderer::render(&raw, setting, &mut __renderer_inner_result)?; Ok(__renderer_inner_result) } } @@ -231,14 +231,14 @@ pub fn register_renderer(input: TokenStream) -> TokenStream { // Register the renderer in the global list let renderer_entry = build_renderer_entry(&struct_name, &previous_type); let renderer_exist_entry = build_renderer_exist_entry(&previous_type); - #[cfg(feature = "general_renderer")] - let general_renderer_entry = build_general_renderer_entry(&previous_type); + #[cfg(feature = "structural_renderer")] + let structural_renderer_entry = build_structural_renderer_entry(&previous_type); let renderer_entry_str = renderer_entry.to_string(); let renderer_exist_entry_str = renderer_exist_entry.to_string(); - #[cfg(feature = "general_renderer")] - let general_renderer_entry_str = general_renderer_entry.to_string(); + #[cfg(feature = "structural_renderer")] + let structural_renderer_entry_str = structural_renderer_entry.to_string(); // Check for duplicate variant before acquiring other locks let variant_name = previous_type @@ -264,21 +264,21 @@ pub fn register_renderer(input: TokenStream) -> TokenStream { let mut renderers = get_global_set(&crate::RENDERERS).lock().unwrap(); let mut renderer_exist = get_global_set(&crate::RENDERERS_EXIST).lock().unwrap(); - #[cfg(feature = "general_renderer")] - let mut general_renderers = get_global_set(&crate::GENERAL_RENDERERS).lock().unwrap(); + #[cfg(feature = "structural_renderer")] + let mut structural_renderers = get_global_set(&crate::STRUCTURAL_RENDERERS).lock().unwrap(); renderers.insert(renderer_entry_str); renderer_exist.insert(renderer_exist_entry_str); - // Only register general renderer if the type is in STRUCTURED_TYPES - #[cfg(feature = "general_renderer")] + // Only register structural renderer if the type is in STRUCTURED_TYPES + #[cfg(feature = "structural_renderer")] { let is_structured = get_global_set(&crate::STRUCTURED_TYPES) .lock() .unwrap() .contains(&variant_name); if is_structured { - general_renderers.insert(general_renderer_entry_str); + structural_renderers.insert(structural_renderer_entry_str); } } diff --git a/mingling_macros/src/structural_data.rs b/mingling_macros/src/structural_data.rs index 593b52d..37fee0f 100644 --- a/mingling_macros/src/structural_data.rs +++ b/mingling_macros/src/structural_data.rs @@ -13,7 +13,7 @@ use crate::get_global_set; /// will fail to compile if `Serialize` is not in scope or implemented. /// /// Also registers the type name in the global `STRUCTURED_TYPES` registry so that -/// the `general_render` match arm is generated by `gen_program!()`. +/// the `structural_render` match arm is generated by `gen_program!()`. pub(crate) fn derive_structural_data(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); let type_name = input.ident; @@ -65,8 +65,8 @@ pub(crate) fn pack_structural(input: TokenStream) -> TokenStream { .unwrap() .insert(type_name_str); - // Struct definition (with Serialize derive, same as pack! under general_renderer) - #[cfg(not(feature = "general_renderer"))] + // Struct definition (with Serialize derive, same as pack! under structural_renderer) + #[cfg(not(feature = "structural_renderer"))] let struct_def = quote! { #(#attrs)* pub struct #type_name { @@ -74,7 +74,7 @@ pub(crate) fn pack_structural(input: TokenStream) -> TokenStream { } }; - #[cfg(feature = "general_renderer")] + #[cfg(feature = "structural_renderer")] let struct_def = quote! { #(#attrs)* #[derive(serde::Serialize)] diff --git a/mling/Cargo.toml b/mling/Cargo.toml index e73fe02..4954320 100644 --- a/mling/Cargo.toml +++ b/mling/Cargo.toml @@ -22,7 +22,7 @@ path = "src/bin/mling.rs" mingling = { path = "../mingling", features = [ "parser", "comp", - "general_renderer", + "structural_renderer", "extra_macros", "yaml_serde_fmt", ] } diff --git a/mling/src/cli.rs b/mling/src/cli.rs index a6d099b..01a836a 100644 --- a/mling/src/cli.rs +++ b/mling/src/cli.rs @@ -12,7 +12,7 @@ use mingling::{ hook::ProgramHook, macros::{chain, help, pack, program_setup, r_println, renderer}, res::ResExitCode, - setup::{ExitCodeSetup, GeneralRendererSetup, HelpFlagSetup, QuietFlagSetup}, + setup::{ExitCodeSetup, StructuralRendererSetup, HelpFlagSetup, QuietFlagSetup}, }; use std::{env::current_dir, path::PathBuf, process::exit, str::FromStr}; @@ -58,7 +58,7 @@ pub fn run() { // Setups program.with_setup(HelpFlagSetup::new(["-h", "--help"])); - program.with_setup(GeneralRendererSetup); + program.with_setup(StructuralRendererSetup); program.with_setup(ExitCodeSetup::default()); program.with_setup(StandardOutputSetup); |
