tauri_typegen/interface/
cli.rs

1use crate::interface::config::GenerateConfig;
2use clap::{Args, Parser, Subcommand};
3use std::path::PathBuf;
4
5#[derive(Parser)]
6#[command(name = "cargo")]
7#[command(bin_name = "cargo")]
8pub struct CargoCli {
9    #[command(subcommand)]
10    pub command: CargoSubcommands,
11}
12
13#[derive(Subcommand)]
14pub enum CargoSubcommands {
15    #[command(name = "tauri-typegen")]
16    TauriTypegen(TauriTypegenArgs),
17}
18
19#[derive(Args)]
20pub struct TauriTypegenArgs {
21    #[command(subcommand)]
22    pub command: TypegenCommands,
23}
24
25#[derive(Subcommand)]
26pub enum TypegenCommands {
27    /// Generate TypeScript models and bindings from Tauri commands
28    Generate {
29        /// Path to the Tauri project source directory (default: ./src-tauri)
30        #[arg(short = 'p', long = "project-path", default_value = "./src-tauri")]
31        project_path: PathBuf,
32
33        /// Output path for generated TypeScript files (default: ./src/generated)
34        #[arg(short = 'o', long = "output-path", default_value = "./src/generated")]
35        output_path: PathBuf,
36
37        /// Validation library to use (zod or none)
38        #[arg(short = 'v', long = "validation", default_value = "zod")]
39        validation_library: String,
40
41        /// Verbose output
42        #[arg(long, action = clap::ArgAction::SetTrue)]
43        verbose: bool,
44
45        /// Generate dependency graph visualization
46        #[arg(long, action = clap::ArgAction::SetTrue)]
47        visualize_deps: bool,
48
49        /// Configuration file path
50        #[arg(short = 'c', long = "config")]
51        config_file: Option<PathBuf>,
52    },
53    /// Initialize configuration for a Tauri project and run initial generation
54    Init {
55        /// Path to the Tauri project source directory (default: ./src-tauri)
56        #[arg(short = 'p', long = "project-path", default_value = "./src-tauri")]
57        project_path: PathBuf,
58
59        /// Output path for generated TypeScript files (default: ./src/generated)
60        #[arg(
61            short = 'g',
62            long = "generated-path",
63            default_value = "./src/generated"
64        )]
65        generated_path: PathBuf,
66
67        /// Output path for configuration file (default: tauri.conf.json)
68        #[arg(short = 'o', long = "output", default_value = "tauri.conf.json")]
69        output_path: PathBuf,
70
71        /// Validation library to use (zod or none)
72        #[arg(short = 'v', long = "validation", default_value = "zod")]
73        validation_library: String,
74
75        /// Verbose output
76        #[arg(long, action = clap::ArgAction::SetTrue)]
77        verbose: bool,
78
79        /// Generate dependency graph visualization
80        #[arg(long, action = clap::ArgAction::SetTrue)]
81        visualize_deps: bool,
82
83        /// Force overwrite existing configuration
84        #[arg(long, action = clap::ArgAction::SetTrue)]
85        force: bool,
86    },
87}
88
89impl From<&TypegenCommands> for GenerateConfig {
90    fn from(cmd: &TypegenCommands) -> Self {
91        match cmd {
92            TypegenCommands::Generate {
93                project_path,
94                output_path,
95                validation_library,
96                verbose,
97                visualize_deps,
98                ..
99            } => GenerateConfig {
100                project_path: project_path.to_string_lossy().to_string(),
101                output_path: output_path.to_string_lossy().to_string(),
102                validation_library: validation_library.clone(),
103                verbose: Some(*verbose),
104                visualize_deps: Some(*visualize_deps),
105                ..Default::default()
106            },
107            TypegenCommands::Init {
108                project_path,
109                generated_path,
110                validation_library,
111                verbose,
112                visualize_deps,
113                ..
114            } => GenerateConfig {
115                project_path: project_path.to_string_lossy().to_string(),
116                output_path: generated_path.to_string_lossy().to_string(),
117                validation_library: validation_library.clone(),
118                verbose: Some(*verbose),
119                visualize_deps: Some(*visualize_deps),
120                ..Default::default()
121            },
122        }
123    }
124}
125
126#[cfg(test)]
127mod tests {
128    use super::*;
129
130    #[test]
131    fn test_default_generate_config_from_cli() {
132        let cmd = TypegenCommands::Generate {
133            project_path: PathBuf::from("./src-tauri"),
134            output_path: PathBuf::from("./src/generated"),
135            validation_library: "zod".to_string(),
136            verbose: false,
137            visualize_deps: false,
138            config_file: None,
139        };
140
141        let config = GenerateConfig::from(&cmd);
142        assert_eq!(config.project_path, "./src-tauri");
143        assert_eq!(config.output_path, "./src/generated");
144        assert_eq!(config.validation_library, "zod");
145        assert!(!config.verbose.unwrap_or(false));
146    }
147
148    #[test]
149    fn test_custom_generate_config_from_cli() {
150        let cmd = TypegenCommands::Generate {
151            project_path: PathBuf::from("./my-tauri"),
152            output_path: PathBuf::from("./types"),
153            validation_library: "none".to_string(),
154            verbose: true,
155            visualize_deps: true,
156            config_file: None,
157        };
158
159        let config = GenerateConfig::from(&cmd);
160        assert_eq!(config.project_path, "./my-tauri");
161        assert_eq!(config.output_path, "./types");
162        assert_eq!(config.validation_library, "none");
163        assert!(config.verbose.unwrap_or(false));
164        assert!(config.visualize_deps.unwrap_or(false));
165    }
166
167    #[test]
168    fn test_default_init_config_from_cli() {
169        let cmd = TypegenCommands::Init {
170            project_path: PathBuf::from("./src-tauri"),
171            generated_path: PathBuf::from("./src/generated"),
172            output_path: PathBuf::from("tauri.conf.json"),
173            validation_library: "zod".to_string(),
174            verbose: false,
175            visualize_deps: false,
176            force: false,
177        };
178
179        let config = GenerateConfig::from(&cmd);
180        assert_eq!(config.project_path, "./src-tauri");
181        assert_eq!(config.output_path, "./src/generated");
182        assert_eq!(config.validation_library, "zod");
183        assert!(!config.verbose.unwrap_or(true));
184        assert!(!config.visualize_deps.unwrap_or(true));
185    }
186
187    #[test]
188    fn test_custom_init_config_from_cli() {
189        let cmd = TypegenCommands::Init {
190            project_path: PathBuf::from("./my-tauri"),
191            generated_path: PathBuf::from("./my-types"),
192            output_path: PathBuf::from("custom.conf.json"),
193            validation_library: "none".to_string(),
194            verbose: true,
195            visualize_deps: true,
196            force: true,
197        };
198
199        let config = GenerateConfig::from(&cmd);
200        assert_eq!(config.project_path, "./my-tauri");
201        assert_eq!(config.output_path, "./my-types");
202        assert_eq!(config.validation_library, "none");
203        assert!(config.verbose.unwrap_or(false));
204        assert!(config.visualize_deps.unwrap_or(false));
205    }
206}