use clap::Parser;
use mtp_sdk::{AuthConfig, AuthProvider, CommandAuth, DescribableBuilder};
#[derive(Parser)]
#[command(
name = "filetool",
version = "1.2.0",
about = "Convert and validate files between formats"
)]
enum Cli {
Convert {
input_file: String,
#[arg(short, long, default_value = "json", value_parser = ["json", "csv", "yaml"])]
format: String,
#[arg(long)]
pretty: bool,
},
Validate {
input_file: String,
#[arg(long)]
strict: bool,
},
Process {
#[arg(long)]
verbose: bool,
},
}
fn main() {
let cli: Cli = DescribableBuilder::new()
.example(
"convert",
"Convert a CSV file to JSON",
"filetool convert data.csv --format json --pretty",
Some("[{\n \"name\": \"Alice\",\n \"age\": 30\n}]"),
)
.example(
"convert",
"Pipe from stdin",
"cat data.csv | filetool convert - --format yaml",
None,
)
.stdin(
"convert",
"text/plain",
"Raw input data (alternative to file path)",
)
.stdout("convert", "application/json", "Converted output")
.example(
"validate",
"Validate a JSON file",
"filetool validate config.json",
Some("{\"valid\": true, \"errors\": []}"),
)
.example(
"process",
"Process a JSON object from stdin",
"echo '{\"name\":\"foo\",\"count\":3}' | filetool process",
Some("{\"status\": \"ok\", \"processed\": \"foo\"}"),
)
.stdin_with_schema(
"process",
"application/json",
"JSON object to process",
serde_json::json!({
"type": "object",
"properties": {
"name": {"type": "string", "description": "Item name"},
"count": {"type": "integer", "description": "Number of items"}
},
"required": ["name"]
}),
)
.stdout("process", "application/json", "Processing result")
.auth(AuthConfig {
required: Some(false),
env_var: "FILETOOL_TOKEN".to_string(),
providers: vec![
AuthProvider {
id: "github".to_string(),
provider_type: "oauth2".to_string(),
display_name: Some("GitHub".to_string()),
authorization_url: Some(
"https://github.com/login/oauth/authorize".to_string(),
),
token_url: Some(
"https://github.com/login/oauth/access_token".to_string(),
),
scopes: Some(vec!["repo".to_string(), "read:user".to_string()]),
client_id: Some("Ov23lixyz".to_string()),
registration_url: None,
instructions: None,
},
AuthProvider {
id: "api-key".to_string(),
provider_type: "api-key".to_string(),
display_name: Some("API Key".to_string()),
authorization_url: None,
token_url: None,
scopes: None,
client_id: None,
registration_url: Some("https://example.com/settings/keys".to_string()),
instructions: Some(
"Create a key at https://example.com/settings/keys".to_string(),
),
},
],
})
.command_auth(
"process",
CommandAuth {
required: Some(true),
scopes: Some(vec!["write".to_string()]),
},
)
.parse();
match cli {
Cli::Convert {
input_file,
format,
pretty,
} => {
println!(
"Converting {} to {}{}",
input_file,
format,
if pretty { " (pretty)" } else { "" }
);
}
Cli::Validate {
input_file,
strict,
} => {
println!(
"Validating {}{}",
input_file,
if strict { " (strict)" } else { "" }
);
}
Cli::Process { verbose } => {
println!("Processing (verbose={})", verbose);
}
}
}