Generated Output Examples

Relevant source files

This page demonstrates the output generation capabilities of axconfig-gen by showing concrete examples of how TOML input configurations are transformed into both cleaned TOML and Rust code outputs. The examples illustrate type mappings, naming conventions, structure preservation, and comment handling across different output formats.

For information about the input TOML configuration format and type annotation system, see TOML Configuration Format. For details on the underlying output generation implementation, see Output Generation.

Transformation Process Overview

The axconfig-gen system processes input TOML configurations through a structured pipeline that preserves semantic meaning while adapting to different output format requirements.

Transformation Pipeline

flowchart TD
subgraph subGraph0["Format-Specific Processing"]
    TOML_CLEAN["TOML CleanupFormatting & Validation"]
    RUST_GEN["Rust Code GenerationConstants & Modules"]
end
INPUT["Input TOML(defconfig.toml)"]
PARSE["TOML Parsing(toml_edit)"]
STRUCT["Config Structure(Config, ConfigItem)"]
TYPE["Type Processing(ConfigType, ConfigValue)"]
TOML_OUT["Generated TOML(output.toml)"]
RUST_OUT["Generated Rust(output.rs)"]

INPUT --> PARSE
PARSE --> STRUCT
RUST_GEN --> RUST_OUT
STRUCT --> TYPE
TOML_CLEAN --> TOML_OUT
TYPE --> RUST_GEN
TYPE --> RUST_OUT
TYPE --> TOML_CLEAN
TYPE --> TOML_OUT

Sources: example-configs/defconfig.toml(L1 - L63)  example-configs/output.toml(L1 - L63)  example-configs/output.rs(L1 - L66) 

Global Configuration Items

Global configuration items defined at the root level of the TOML are transformed into top-level constants in Rust output while being preserved with consistent formatting in TOML output.

Input TOML Configuration:

# Architecture identifier.
arch = "x86_64"             # str
# Platform identifier.
plat = "x86_64-qemu-q35"    # str
# Number of CPUs.
smp = 1                     # uint

Generated TOML Output:

# Architecture identifier.
arch = "x86_64" # str
# Platform identifier.
plat = "x86_64-qemu-q35" # str
# Number of CPUs.
smp = 1 # uint

Generated Rust Output:

/// Architecture identifier.
pub const ARCH: &str = "x86_64";
/// Platform identifier.
pub const PLAT: &str = "x86_64-qemu-q35";
/// Number of CPUs.
pub const SMP: usize = 1;

Transformations Applied:

AspectInputTOML OutputRust Output
NamingarcharchARCH
Type"x86_64"(str)"x86_64" # str&str
Comments# Architecture identifier.Preserved/// Architecture identifier.
FormattingVariable spacingConsistent spacingRust doc comments

Sources: example-configs/defconfig.toml(L1 - L6)  example-configs/output.toml(L1 - L6)  example-configs/output.rs(L1 - L6) 

Sectioned Configuration

TOML table sections are transformed into Rust modules, maintaining the hierarchical organization while adapting naming conventions for each output format.

Input TOML Configuration:

[kernel]
# Stack size of each task.
task-stack-size = 0     # uint
# Number of timer ticks per second (Hz).
ticks-per-sec = 0       # uint

Generated TOML Output:

[kernel]
# Stack size of each task.
task-stack-size = 0 # uint
# Number of timer ticks per second (Hz).
ticks-per-sec = 0 # uint

Generated Rust Output:

///
/// Kernel configs
///
pub mod kernel {
    /// Stack size of each task.
    pub const TASK_STACK_SIZE: usize = 0;
    /// Number of timer ticks per second (Hz).
    pub const TICKS_PER_SEC: usize = 0;
}

Structure Mapping:

flowchart TD
TOML_TABLE["[kernel]TOML Table"]
RUST_MOD["pub mod kernelRust Module"]
TOML_ITEM1["task-stack-size = 0"]
TOML_ITEM2["ticks-per-sec = 0"]
RUST_CONST1["pub const TASK_STACK_SIZE: usize = 0"]
RUST_CONST2["pub const TICKS_PER_SEC: usize = 0"]

RUST_MOD --> RUST_CONST1
RUST_MOD --> RUST_CONST2
TOML_ITEM1 --> RUST_CONST1
TOML_ITEM2 --> RUST_CONST2
TOML_TABLE --> TOML_ITEM1
TOML_TABLE --> TOML_ITEM2

Sources: example-configs/defconfig.toml(L11 - L16)  example-configs/output.toml(L32 - L37)  example-configs/output.rs(L33 - L39) 

Complex Data Types

Array and tuple types demonstrate sophisticated type mapping between TOML array syntax and Rust slice references, including proper handling of nested structures.

Input TOML Configuration:

[devices]
# MMIO regions with format (`base_paddr`, `size`).
mmio-regions = [
    ["0xb000_0000", "0x1000_0000"], # PCI config space
    ["0xfe00_0000", "0xc0_0000"],   # PCI devices
    ["0xfec0_0000", "0x1000"],      # IO APIC
]                           # [(uint, uint)]

Generated TOML Output:

[devices]
# MMIO regions with format (`base_paddr`, `size`).
mmio-regions = [
    ["0xb000_0000", "0x1000_0000"],
    ["0xfe00_0000", "0xc0_0000"],
    ["0xfec0_0000", "0x1000"],
] # [(uint, uint)]

Generated Rust Output:

pub mod devices {
    /// MMIO regions with format (`base_paddr`, `size`).
    pub const MMIO_REGIONS: &[(usize, usize)] = &[
        (0xb000_0000, 0x1000_0000),
        (0xfe00_0000, 0xc0_0000),
        (0xfec0_0000, 0x1000),
    ];
}

Type System Mappings:

flowchart TD
subgraph subGraph1["Rust Types"]
    RUST_SLICE["Slice Reference&[(usize, usize)]"]
    RUST_TUPLE["Tuple Literals(0xb000_0000, 0x1000_0000)"]
    RUST_TYPE["Rust Typeusize"]
end
subgraph subGraph0["TOML Types"]
    TOML_ARR["Array of Arrays[[str, str], ...]"]
    TOML_STR["String Literals'0xb000_0000'"]
    TOML_TYPE["Type Annotation# [(uint, uint)]"]
end

TOML_ARR --> RUST_SLICE
TOML_STR --> RUST_TUPLE
TOML_TYPE --> RUST_TYPE

Sources: example-configs/defconfig.toml(L48 - L54)  example-configs/output.toml(L13 - L19)  example-configs/output.rs(L13 - L19) 

Type System and Naming Conventions

The transformation process applies consistent rules for type mapping and identifier naming across output formats.

Type Mapping Rules:

TOML Type AnnotationTOML ValueRust TypeRust Value
# str"x86_64"&str"x86_64"
# uint1usize1
# uint"0xffff_ff80_0000_0000"usize0xffff_ff80_0000_0000
# [(uint, uint)][["0x1000", "0x2000"]]&[(usize, usize)]&[(0x1000, 0x2000)]

Naming Convention Transformations:

flowchart TD
subgraph subGraph2["Rust Output"]
    SNAKE["SCREAMING_SNAKE_CASETASK_STACK_SIZE"]
    MODULE["snake_case modulesection_name"]
end
subgraph subGraph1["TOML Output"]
    KEBAB_OUT["kebab-casetask-stack-size"]
    SECTION_OUT["[section-name]"]
end
subgraph subGraph0["Input Identifiers"]
    KEBAB["kebab-casetask-stack-size"]
    SECTION["[section-name]"]
end

KEBAB --> KEBAB_OUT
KEBAB --> SNAKE
SECTION --> MODULE
SECTION --> SECTION_OUT

Hexadecimal Value Processing:

Large hexadecimal values in TOML strings are parsed and converted to native Rust integer literals:

  • Input: kernel-base-vaddr = "0xffff_ff80_0020_0000"
  • Output: pub const KERNEL_BASE_VADDR: usize = 0xffff_ff80_0020_0000;

Sources: example-configs/defconfig.toml(L29)  example-configs/output.rs(L52)  example-configs/defconfig.toml(L32)  example-configs/output.rs(L62) 

Comment and Documentation Preservation

Comments from the input TOML are preserved and transformed appropriately for each output format, maintaining documentation context across transformations.

Comment Transformation Rules:

Input LocationTOML OutputRust Output
Line commentsPreserved as-isConverted to///doc comments
Section headersPreserved with formattingConverted to module doc comments
Type annotationsPreserved inlineEmbedded in type signatures

The generated outputs maintain full traceability to the original configuration intent while adapting to the idioms and conventions of their respective formats.

Sources: example-configs/defconfig.toml(L1 - L63)  example-configs/output.toml(L1 - L63)  example-configs/output.rs(L1 - L66)