{#- 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()
}