baobao_codegen/traits.rs
1//! Language-agnostic code generation traits.
2
3use std::path::Path;
4
5use baobao_core::{ArgType, ContextFieldType};
6use eyre::Result;
7
8/// Trait for language-specific code generators.
9///
10/// Implement this trait to add support for generating CLI code in a new language.
11pub trait LanguageCodegen {
12 /// Language identifier (e.g., "rust", "typescript", "go")
13 fn language(&self) -> &'static str;
14
15 /// File extension for generated source files (e.g., "rs", "ts", "go")
16 fn file_extension(&self) -> &'static str;
17
18 /// Preview generated files without writing to disk
19 fn preview(&self) -> Vec<PreviewFile>;
20
21 /// Generate all files into the specified output directory
22 fn generate(&self, output_dir: &Path) -> Result<GenerateResult>;
23}
24
25/// Result of code generation
26#[derive(Debug, Default)]
27pub struct GenerateResult {
28 /// Handler files that were created (stubs for new commands)
29 pub created_handlers: Vec<String>,
30 /// Handler files that exist but are no longer used
31 pub orphan_handlers: Vec<String>,
32}
33
34/// A generated file for preview
35#[derive(Debug)]
36pub struct PreviewFile {
37 /// Relative path from output directory
38 pub path: String,
39 /// File content
40 pub content: String,
41}
42
43/// Trait for mapping schema types to language-specific type strings.
44///
45/// Implement this trait for each target language to provide type mappings.
46pub trait TypeMapper {
47 /// The target language name
48 fn language(&self) -> &'static str;
49
50 /// Map an argument type to a language-specific type string
51 fn map_arg_type(&self, arg_type: ArgType) -> &'static str;
52
53 /// Map an optional argument type (e.g., `Option<String>` in Rust, `string | undefined` in TS)
54 fn map_optional_arg_type(&self, arg_type: ArgType) -> String {
55 // Default implementation - languages can override
56 format!("Option<{}>", self.map_arg_type(arg_type))
57 }
58
59 /// Map a context field type to a language-specific type string
60 fn map_context_type(&self, field_type: &ContextFieldType) -> &'static str;
61}