Skip to main content

filetool/
filetool.rs

1//! Example CLI tool demonstrating mtp-sdk with auth support.
2//!
3//! Run:
4//!   cargo run --example filetool -- --describe
5//!   cargo run --example filetool -- convert data.csv --format json
6
7use clap::Parser;
8use mtp_sdk::{AuthConfig, AuthProvider, CommandAuth, DescribableBuilder};
9
10#[derive(Parser)]
11#[command(
12    name = "filetool",
13    version = "1.2.0",
14    about = "Convert and validate files between formats"
15)]
16enum Cli {
17    /// Convert a file from one format to another
18    Convert {
19        /// Input file path
20        input_file: String,
21
22        /// Output format
23        #[arg(short, long, default_value = "json", value_parser = ["json", "csv", "yaml"])]
24        format: String,
25
26        /// Pretty-print output
27        #[arg(long)]
28        pretty: bool,
29    },
30
31    /// Check if a file is well-formed and valid
32    Validate {
33        /// File to validate
34        input_file: String,
35
36        /// Enable strict validation mode
37        #[arg(long)]
38        strict: bool,
39    },
40
41    /// Process structured JSON input from stdin
42    Process {
43        /// Enable verbose output
44        #[arg(long)]
45        verbose: bool,
46    },
47}
48
49fn main() {
50    let cli: Cli = DescribableBuilder::new()
51        .example(
52            "convert",
53            "Convert a CSV file to JSON",
54            "filetool convert data.csv --format json --pretty",
55            Some("[{\n  \"name\": \"Alice\",\n  \"age\": 30\n}]"),
56        )
57        .example(
58            "convert",
59            "Pipe from stdin",
60            "cat data.csv | filetool convert - --format yaml",
61            None,
62        )
63        .stdin(
64            "convert",
65            "text/plain",
66            "Raw input data (alternative to file path)",
67        )
68        .stdout("convert", "application/json", "Converted output")
69        .example(
70            "validate",
71            "Validate a JSON file",
72            "filetool validate config.json",
73            Some("{\"valid\": true, \"errors\": []}"),
74        )
75        .example(
76            "process",
77            "Process a JSON object from stdin",
78            "echo '{\"name\":\"foo\",\"count\":3}' | filetool process",
79            Some("{\"status\": \"ok\", \"processed\": \"foo\"}"),
80        )
81        .stdin_with_schema(
82            "process",
83            "application/json",
84            "JSON object to process",
85            serde_json::json!({
86                "type": "object",
87                "properties": {
88                    "name": {"type": "string", "description": "Item name"},
89                    "count": {"type": "integer", "description": "Number of items"}
90                },
91                "required": ["name"]
92            }),
93        )
94        .stdout("process", "application/json", "Processing result")
95        .auth(AuthConfig {
96            required: Some(false),
97            env_var: "FILETOOL_TOKEN".to_string(),
98            providers: vec![
99                AuthProvider {
100                    id: "github".to_string(),
101                    provider_type: "oauth2".to_string(),
102                    display_name: Some("GitHub".to_string()),
103                    authorization_url: Some(
104                        "https://github.com/login/oauth/authorize".to_string(),
105                    ),
106                    token_url: Some(
107                        "https://github.com/login/oauth/access_token".to_string(),
108                    ),
109                    scopes: Some(vec!["repo".to_string(), "read:user".to_string()]),
110                    client_id: Some("Ov23lixyz".to_string()),
111                    registration_url: None,
112                    instructions: None,
113                },
114                AuthProvider {
115                    id: "api-key".to_string(),
116                    provider_type: "api-key".to_string(),
117                    display_name: Some("API Key".to_string()),
118                    authorization_url: None,
119                    token_url: None,
120                    scopes: None,
121                    client_id: None,
122                    registration_url: Some("https://example.com/settings/keys".to_string()),
123                    instructions: Some(
124                        "Create a key at https://example.com/settings/keys".to_string(),
125                    ),
126                },
127            ],
128        })
129        .command_auth(
130            "process",
131            CommandAuth {
132                required: Some(true),
133                scopes: Some(vec!["write".to_string()]),
134            },
135        )
136        .parse();
137
138    match cli {
139        Cli::Convert {
140            input_file,
141            format,
142            pretty,
143        } => {
144            println!(
145                "Converting {} to {}{}",
146                input_file,
147                format,
148                if pretty { " (pretty)" } else { "" }
149            );
150        }
151        Cli::Validate {
152            input_file,
153            strict,
154        } => {
155            println!(
156                "Validating {}{}",
157                input_file,
158                if strict { " (strict)" } else { "" }
159            );
160        }
161        Cli::Process { verbose } => {
162            println!("Processing (verbose={})", verbose);
163        }
164    }
165}