Output Generation
Relevant source files
This section covers the output generation system in axconfig-gen, which converts parsed configuration structures into formatted output strings. The system supports generating both TOML files and Rust source code from configuration data, handling proper formatting, type annotations, and structural organization.
For information about the core data structures being formatted, see Core Data Structures. For details about the type system that drives code generation, see Type System.
Purpose and Scope
The output generation system serves as the final stage of the configuration processing pipeline, transforming internal Config, ConfigItem, and ConfigValue structures into human-readable and machine-consumable formats. It handles:
- Format Selection: Supporting TOML and Rust code output formats
- Structural Organization: Managing tables, modules, and hierarchical output
- Type-Aware Generation: Converting values according to their configured types
- Formatting and Indentation: Ensuring readable, properly formatted output
- Comment Preservation: Maintaining documentation and type annotations
Output Format Architecture
The system centers around the OutputFormat enum and Output writer, which coordinate the transformation process.
Output Format Selection
flowchart TD
subgraph subGraph2["Generation Methods"]
TABLE_BEGIN["table_begin()"]
TABLE_END["table_end()"]
WRITE_ITEM["write_item()"]
PRINT_LINES["print_lines()"]
end
subgraph subGraph1["Writer System"]
OUTPUT["Output"]
WRITER_STATE["writer statefmt: OutputFormatindent: usizeresult: String"]
end
subgraph subGraph0["Format Selection"]
OF["OutputFormat"]
TOML_FMT["OutputFormat::Toml"]
RUST_FMT["OutputFormat::Rust"]
end
TOML_OUT["[table]key = value # type"]
RUST_OUT["pub mod table {pub const KEY: Type = value;}"]
OF --> OUTPUT
OF --> RUST_FMT
OF --> TOML_FMT
OUTPUT --> PRINT_LINES
OUTPUT --> TABLE_BEGIN
OUTPUT --> TABLE_END
OUTPUT --> WRITER_STATE
OUTPUT --> WRITE_ITEM
RUST_FMT --> RUST_OUT
TOML_FMT --> TOML_OUT
Sources: axconfig-gen/src/output.rs(L3 - L32) axconfig-gen/src/output.rs(L34 - L48)
Value Conversion Pipeline
The conversion from internal values to output strings follows a type-aware transformation process.
Value to Output Conversion Flow
Sources: axconfig-gen/src/value.rs(L92 - L102) axconfig-gen/src/value.rs(L226 - L241) axconfig-gen/src/value.rs(L243 - L288)
Output Writer Implementation
The Output struct manages the formatting state and provides methods for building structured output.
Core Writer Methods
| Method | Purpose | TOML Behavior | Rust Behavior |
|---|---|---|---|
| table_begin() | Start a configuration section | Writes[table-name]header | Createspub mod table_name { |
| table_end() | End a configuration section | No action needed | Writes closing} |
| write_item() | Output a key-value pair | key = value # type | pub const KEY: Type = value; |
| print_lines() | Handle multi-line comments | Preserves#comments | Converts to///doc comments |
Sources: axconfig-gen/src/output.rs(L71 - L93) axconfig-gen/src/output.rs(L95 - L136)
Formatting and Indentation
The system maintains proper indentation for nested structures:
flowchart TD
subgraph subGraph1["Rust Module Nesting"]
MOD_BEGIN["table_begin() → indent += 4"]
MOD_END["table_end() → indent -= 4"]
CONST_WRITE["write_item() uses current indent"]
end
subgraph subGraph0["Indentation Management"]
INDENT_STATE["indent: usize"]
PRINTLN_FMT["println_fmt()"]
SPACES["format!('{:indent$}', '')"]
end
CONST_WRITE --> INDENT_STATE
INDENT_STATE --> PRINTLN_FMT
MOD_BEGIN --> INDENT_STATE
MOD_END --> INDENT_STATE
PRINTLN_FMT --> SPACES
Sources: axconfig-gen/src/output.rs(L54 - L60) axconfig-gen/src/output.rs(L82 - L84) axconfig-gen/src/output.rs(L89 - L92)
Type-Specific Value Generation
Different value types require specialized conversion logic for both TOML and Rust output formats.
Primitive Types
| Value Type | TOML Output | Rust Output |
|---|---|---|
| Boolean | true,false | true,false |
| Integer | 42,0xdead_beef | 42,0xdead_beef |
| String | "hello" | "hello" |
| Numeric String | "0xff" | 0xff(converted to number) |
Sources: axconfig-gen/src/value.rs(L228 - L230) axconfig-gen/src/value.rs(L245 - L255)
Collection Types
Array Conversion Logic
flowchart TD
subgraph subGraph2["Rust Output"]
SIMPLE_RUST["&[elem1, elem2, elem3]"]
NESTED_RUST["&[elem1,elem2,]"]
end
subgraph subGraph1["TOML Output"]
SIMPLE_TOML["[elem1, elem2, elem3]"]
NESTED_TOML["[elem1,elem2]"]
end
subgraph subGraph0["Array Processing"]
ARRAY_VAL["Value::Array"]
CHECK_NESTED["contains nested arrays?"]
ELEMENTS["convert each element"]
end
ARRAY_VAL --> CHECK_NESTED
CHECK_NESTED --> ELEMENTS
CHECK_NESTED --> NESTED_RUST
CHECK_NESTED --> NESTED_TOML
CHECK_NESTED --> SIMPLE_RUST
CHECK_NESTED --> SIMPLE_TOML
ELEMENTS --> NESTED_RUST
ELEMENTS --> NESTED_TOML
ELEMENTS --> SIMPLE_RUST
ELEMENTS --> SIMPLE_TOML
Sources: axconfig-gen/src/value.rs(L231 - L240) axconfig-gen/src/value.rs(L267 - L285)
Tuple vs Array Distinction
The system distinguishes between homogeneous arrays and heterogeneous tuples:
| Configuration | Type | TOML Output | Rust Output |
|---|---|---|---|
| [1, 2, 3] | [uint] | [1, 2, 3] | &[1, 2, 3] |
| [1, "a", true] | (uint, str, bool) | [1, "a", true] | (1, "a", true) |
Sources: axconfig-gen/src/value.rs(L256 - L265) axconfig-gen/src/value.rs(L267 - L285)
Name Transformation
The system applies consistent naming conventions when converting between formats:
Identifier Transformation Rules
flowchart TD
subgraph subGraph0["TOML to Rust Naming"]
TOML_KEY["TOML key: 'some-config-key'"]
MOD_TRANSFORM["mod_name(): replace '-' with '_'"]
CONST_TRANSFORM["const_name(): UPPERCASE + replace '-' with '_'"]
RUST_MOD["Rust module: 'some_config_key'"]
RUST_CONST["Rust constant: 'SOME_CONFIG_KEY'"]
end
CONST_TRANSFORM --> RUST_CONST
MOD_TRANSFORM --> RUST_MOD
TOML_KEY --> CONST_TRANSFORM
TOML_KEY --> MOD_TRANSFORM
Sources: axconfig-gen/src/output.rs(L138 - L144)
Error Handling in Output Generation
The system provides comprehensive error handling for output generation scenarios:
| Error Condition | When It Occurs | Error Type |
|---|---|---|
| Unknown type for key | Type inference fails and no explicit type | ConfigErr::Other |
| Value type mismatch | Value doesn't match expected type | ConfigErr::ValueTypeMismatch |
| Array length mismatch | Tuple and array length differ | ConfigErr::ValueTypeMismatch |
Sources: axconfig-gen/src/output.rs(L120 - L125) axconfig-gen/src/value.rs(L257 - L259)
The output generation system provides a robust foundation for transforming configuration data into multiple target formats while preserving type information and maintaining readable formatting conventions.