ggen-cli-lib 26.6.11

CLI interface for ggen
Documentation
{#- Main entry point for a generated clap-noun-verb CLI
    This is the complete main.rs -- includes mod declarations for
    domain and error modules, all noun modules, and the run() entry.

    Expected variables:
    - interface_name: string (e.g., "ggen")
    - interface_summary: string (e.g., "Ontology-governed compiler interface")
    - commands: array of { name, summary, description, subcommands[] }
      - subcommands[]: { name, summary, about, options[], positional_arguments[],
                         constraints[], examples[] }
        - options[]: { name, long_name, type (flag/value), summary, description,
                       required, global }
        - positional_arguments[]: { name, summary, required }
        - constraints[]: { type, source, target }
        - examples[]: { text }
    - global_options: array of { name, long_name, type, summary, global }
-#}
//! {{ interface_name }} -- {{ interface_summary }}
//!
//! Generated by ggen -- governed enterprise text compiler
//!
//! Architecture:
//! - CLI Layer (this file): Argument parsing via #[noun]/#[verb] macros
//! - Domain Layer (domain.rs): Pure business logic -- implement your logic there
//! - Error Types (error.rs): Type-safe error handling

use clap_noun_verb::Result;
use clap_noun_verb_macros::noun;
use serde::Serialize;

mod domain;
mod error;

use error::CliError;

{%- for command in commands %}
{%- if command.subcommands and command.subcommands | length > 0 %}

// ============================================================================
// {{ command.name | upper }} -- {{ command.summary }}
// ============================================================================

#[noun("{{ command.name }}", "{{ command.summary }}")]
mod {{ command.name | snake }} {
    use super::*;
    use clap_noun_verb_macros::verb;

    {%- for subcmd in command.subcommands %}
    /// {{ subcmd.summary }}
    ///
    {%- if subcmd.about %}
    /// {{ subcmd.about }}
    ///
    {%- endif %}
    {%- if subcmd.constraints %}
    {%- for constraint in subcmd.constraints %}
    /// Constraint: {{ constraint.type }}({{ constraint.source }}, {{ constraint.target }})
    ///
    {%- endfor %}
    {%- endif %}
    {%- if subcmd.examples %}
    {%- for example in subcmd.examples %}
    /// Example: {{ example.text }}
    ///
    {%- endfor %}
    {%- endif %}
    #[verb("{{ subcmd.name }}")]
    pub fn {{ subcmd.name | snake }}(
        {%- for arg in subcmd.positional_arguments %}
        {%- if arg.required %}
        {{ arg.name | snake }}: String,
        {%- else %}
        {{ arg.name | snake }}: Option<String>,
        {%- endif %}
        {%- endfor %}
        {%- for opt in subcmd.options %}
        {%- if opt.global %}{% continue %}{% endif %}
        {%- if opt.type == "flag" %}
        {{ opt.name | replace(from="-", to="_") }}: bool,
        {%- elif opt.required %}
        {{ opt.name | replace(from="-", to="_") }}: String,
        {%- else %}
        {{ opt.name | replace(from="-", to="_") }}: Option<String>,
        {%- endif %}
        {%- endfor %}
    ) -> Result<serde_json::Value> {
        let result = crate::domain::{{ command.name | snake }}::{{ subcmd.name | snake }}(
            {%- for arg in subcmd.positional_arguments %}
            {{ arg.name | snake }},
            {%- endfor %}
            {%- for opt in subcmd.options %}
            {%- if opt.global %}{% continue %}{% endif %}
            {{ opt.name | replace(from="-", to="_") }},
            {%- endfor %}
        ).map_err(|e| CliError::from(e))?;
        Ok(serde_json::to_value(&result).map_err(|e| CliError::Serialization(e.to_string()))?)
    }

    {%- endfor %}
}

{%- elif command.special %}
{#- Special commands (e.g., sync) are root-level verbs #}

// ============================================================================
// {{ command.name | upper }} -- {{ command.summary }}
// ============================================================================

/// {{ command.summary }}
///
{%- if command.description %}
/// {{ command.description }}
///
{%- endif %}
{%- if command.examples %}
{%- for example in command.examples %}
/// Example: {{ example.text }}
///
{%- endfor %}
{%- endif %}
#[verb("{{ command.name }}", "root")]
pub fn {{ command.name | snake }}(
    {%- for opt in command.options %}
    {%- if opt.type == "flag" %}
    {{ opt.name | replace(from="-", to="_") }}: Option<bool>,
    {%- else %}
    {{ opt.name | replace(from="-", to="_") }}: Option<String>,
    {%- endif %}
    {%- if not loop.last %}, {% endif %}
    {%- endfor %}
) -> Result<serde_json::Value> {
    let result = crate::domain::{{ command.name | snake }}::run(
        {%- for opt in command.options %}
        {{ opt.name | replace(from="-", to="_") }},
        {%- endfor %}
    ).map_err(|e| CliError::from(e))?;
    Ok(serde_json::to_value(&result).map_err(|e| CliError::Serialization(e.to_string()))?)
}

{%- endif %}
{%- endfor %}

fn main() -> Result<()> {
    clap_noun_verb::run()
}