use std::ffi::OsString;
use std::path::PathBuf;
use clap::{arg, Command};
fn cli() -> Command {
Command::new("git" )
.about("A fictional versioning CLI" )
.subcommand_required(true )
.arg_required_else_help(true )
.allow_external_subcommands(true )
.subcommand(
Command::new("clone" )
.about("Clones repos" )
.arg(arg!(<REMOTE> "The remote to clone" ))
.arg_required_else_help(true ),
)
.subcommand(
Command::new("diff" )
.about("Compare two commits" )
.arg(arg!(base: [COMMIT]))
.arg(arg!(head: [COMMIT]))
.arg(arg!(path: [PATH]).last(true ))
.arg(
arg!(--color <WHEN>)
.value_parser(["always" , "auto" , "never" ])
.num_args(0 ..=1 )
.require_equals(true )
.default_value("auto" )
.default_missing_value("always" ),
),
)
.subcommand(
Command::new("push" )
.about("pushes things" )
.arg(arg!(<REMOTE> "The remote to target" ))
.arg_required_else_help(true ),
)
.subcommand(
Command::new("add" )
.about("adds things" )
.arg_required_else_help(true )
.arg(arg!(<PATH> ... "Stuff to add" ).value_parser(clap::value_parser!(PathBuf))),
)
.subcommand(
Command::new("stash" )
.args_conflicts_with_subcommands(true )
.flatten_help(true )
.args(push_args())
.subcommand(Command::new("push" ).args(push_args()))
.subcommand(Command::new("pop" ).arg(arg!([STASH])))
.subcommand(Command::new("apply" ).arg(arg!([STASH]))),
)
}
fn push_args() -> Vec<clap::Arg> {
vec![arg!(-m --message <MESSAGE>)]
}
fn main() {
let matches = cli().get_matches();
match matches.subcommand() {
Some(("clone" , sub_matches)) => {
println!(
"Cloning {}" ,
sub_matches.get_one::<String>("REMOTE" ).expect("required" )
);
}
Some(("diff" , sub_matches)) => {
let color = sub_matches
.get_one::<String>("color" )
.map(|s| s.as_str())
.expect("defaulted in clap" );
let mut base = sub_matches.get_one::<String>("base" ).map(|s| s.as_str());
let mut head = sub_matches.get_one::<String>("head" ).map(|s| s.as_str());
let mut path = sub_matches.get_one::<String>("path" ).map(|s| s.as_str());
if path.is_none() {
path = head;
head = None;
if path.is_none() {
path = base;
base = None;
}
}
let base = base.unwrap_or("stage" );
let head = head.unwrap_or("worktree" );
let path = path.unwrap_or("" );
println!("Diffing {base}..{head} {path} (color={color})" );
}
Some(("push" , sub_matches)) => {
println!(
"Pushing to {}" ,
sub_matches.get_one::<String>("REMOTE" ).expect("required" )
);
}
Some(("add" , sub_matches)) => {
let paths = sub_matches
.get_many::<PathBuf>("PATH" )
.into_iter()
.flatten()
.collect::<Vec<_>>();
println!("Adding {paths:?}" );
}
Some(("stash" , sub_matches)) => {
let stash_command = sub_matches.subcommand().unwrap_or(("push" , sub_matches));
match stash_command {
("apply" , sub_matches) => {
let stash = sub_matches.get_one::<String>("STASH" );
println!("Applying {stash:?}" );
}
("pop" , sub_matches) => {
let stash = sub_matches.get_one::<String>("STASH" );
println!("Popping {stash:?}" );
}
("push" , sub_matches) => {
let message = sub_matches.get_one::<String>("message" );
println!("Pushing {message:?}" );
}
(name, _) => {
unreachable!("Unsupported subcommand `{name}`" )
}
}
}
Some((ext, sub_matches)) => {
let args = sub_matches
.get_many::<OsString>("" )
.into_iter()
.flatten()
.collect::<Vec<_>>();
println!("Calling out to {ext:?} with {args:?}" );
}
_ => unreachable!(), // If all subcommands are defined above, anything else is unreachable!()
}
// Continued program logic goes here...
}
Messung V0.5 in Prozent C=91 H=97 G=93
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-06-19)
¤
*© Formatika GbR, Deutschland