Files
2025-11-30 09:04:14 +08:00

144 lines
3.6 KiB
Rust
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/// ValueEnum Template for Type-Safe Options
///
/// This template demonstrates:
/// - ValueEnum trait for constrained choices
/// - Type-safe option selection
/// - Automatic validation and help text
/// - Pattern matching on enums
use clap::{Parser, ValueEnum};
/// Output format options
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
enum Format {
/// JavaScript Object Notation
Json,
/// YAML Ain't Markup Language
Yaml,
/// Tom's Obvious, Minimal Language
Toml,
/// Comma-Separated Values
Csv,
}
/// Log level options
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
enum LogLevel {
/// Detailed debug information
Debug,
/// General information
Info,
/// Warning messages
Warn,
/// Error messages only
Error,
}
/// Color output mode
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
enum ColorMode {
/// Always use colors
Always,
/// Never use colors
Never,
/// Automatically detect (default)
Auto,
}
#[derive(Parser)]
#[command(name = "converter")]
#[command(about = "Convert data between formats with type-safe options")]
struct Cli {
/// Input file
input: std::path::PathBuf,
/// Output format
#[arg(short, long, value_enum, default_value_t = Format::Json)]
format: Format,
/// Log level
#[arg(short, long, value_enum, default_value_t = LogLevel::Info)]
log_level: LogLevel,
/// Color mode for output
#[arg(long, value_enum, default_value_t = ColorMode::Auto)]
color: ColorMode,
/// Pretty print output (for supported formats)
#[arg(short, long)]
pretty: bool,
}
fn main() {
let cli = Cli::parse();
// Configure logging based on log level
match cli.log_level {
LogLevel::Debug => println!("🔍 Debug logging enabled"),
LogLevel::Info => println!(" Info logging enabled"),
LogLevel::Warn => println!("⚠️ Warning logging enabled"),
LogLevel::Error => println!("❌ Error logging only"),
}
// Check color mode
let use_colors = match cli.color {
ColorMode::Always => true,
ColorMode::Never => false,
ColorMode::Auto => atty::is(atty::Stream::Stdout),
};
if use_colors {
println!("🎨 Color output enabled");
}
// Process based on format
println!("Converting {} to {:?}", cli.input.display(), cli.format);
match cli.format {
Format::Json => {
println!("Converting to JSON{}", if cli.pretty { " (pretty)" } else { "" });
// JSON conversion logic here
}
Format::Yaml => {
println!("Converting to YAML");
// YAML conversion logic here
}
Format::Toml => {
println!("Converting to TOML");
// TOML conversion logic here
}
Format::Csv => {
println!("Converting to CSV");
// CSV conversion logic here
}
}
println!("✓ Conversion complete");
}
// Helper function to check if stdout is a terminal (for color auto-detection)
mod atty {
pub enum Stream {
Stdout,
}
pub fn is(_stream: Stream) -> bool {
// Simple implementation - checks if stdout is a TTY
#[cfg(unix)]
{
unsafe { libc::isatty(libc::STDOUT_FILENO) != 0 }
}
#[cfg(not(unix))]
{
false
}
}
}
// Example usage:
//
// cargo run -- input.txt --format json --log-level debug
// cargo run -- data.yml --format toml --color always --pretty
// cargo run -- config.json --format yaml --log-level warn