Last active
June 14, 2022 23:10
-
-
Save Thell/1fc7bac0a1f65206b821f03b5dbde587 to your computer and use it in GitHub Desktop.
wip - beginner clap definitions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use clap::{Args, ArgGroup, Parser, Subcommand}; | |
#[derive(Parser)] | |
#[clap(author, version, about, long_about = None)] | |
#[clap(propagate_version = true)] | |
struct Cli { | |
#[clap(subcommand)] | |
command: Commands, | |
} | |
#[derive(Subcommand)] | |
enum Commands { | |
/// Work with PAD files | |
/// | |
/// The PAD format is a simple file format that is used to store compressed data. | |
/// A meta file is stored in the same directory as the package files (compressed data) | |
/// and contains tables for archive packages, paths, files, and meta records | |
/// (hashes, sizes, and other information). | |
/// | |
/// Lookup by hash is done as a search over the meta records hash field. | |
/// Lookup by infile is done by searching exact matches over all path/filenames. | |
/// Filtering with regex is done over the path records and then over the file records. | |
Pad(Pad), | |
} | |
#[derive(Debug, Args)] | |
struct Pad { | |
#[clap(subcommand)] | |
command: Option<PadCommands>, | |
} | |
#[derive(Debug, Subcommand)] | |
#[clap(arg_required_else_help = true)] | |
enum PadCommands { | |
/// Report meta file changes | |
/// | |
/// Scans a meta file's package and meta tables to identify changes at the file level. | |
Changes(PadChanges), | |
/// Extract archive contents to a directory | |
/// | |
/// Recreates the directory structure and extracts the files from the archive. | |
Extract(PadExtract), | |
/// Fetch a archive contents to a directory | |
/// | |
/// Fetch a meta version or the packages for a meta version needed to extract contents | |
/// from the archive using given filters. If no filters are given, all packages are fetched. | |
Fetch(PadFetch), | |
/// Report meta data | |
List(PadList), | |
} | |
#[derive(Debug, Args)] | |
#[clap(group = ArgGroup::new("PadSubCommandCommonArgs").multiple(true).required(false))] | |
struct PadSubCommandCommonArgs { | |
/// Filter meta records by archive path using regex | |
#[clap(long, display_order = 900, conflicts_with = "hash", conflicts_with = "infile")] | |
query_path: Option<String>, | |
/// Filter meta records by archive name using regex | |
#[clap(long, display_order = 900, conflicts_with = "hash", conflicts_with = "infile")] | |
query_file: Option<String>, | |
/// Query meta records using a specific hashlittle hash | |
#[clap(long, display_order = 900, conflicts_with = "query-path", conflicts_with = "query-file", conflicts_with = "infile")] | |
hash: Option<String>, | |
/// Filter meta records with paths/filenames in input file | |
#[clap(long, display_order = 900, conflicts_with = "query-path", conflicts_with = "query-file", conflicts_with = "hash")] | |
infile: Option<String>, | |
} | |
#[derive(Debug, Args)] | |
#[clap(arg_required_else_help = true)] | |
struct PadChanges { | |
/// From meta file | |
#[clap(short, long, display_order = 1)] | |
from_file: String, | |
/// To meta file | |
#[clap(short, long, display_order = 2)] | |
to_file: String, | |
/// Output file | |
#[clap(short, long, display_order = 3)] | |
out_file: Option<String>, | |
#[clap(flatten)] | |
common: PadSubCommandCommonArgs, | |
} | |
#[derive(Debug, Args)] | |
#[clap(arg_required_else_help = true)] | |
struct PadExtract { | |
/// Directory containing archive contents | |
#[clap(short, long, display_order = 1)] | |
from_dir: String, | |
/// Output directory | |
#[clap(short, long, display_order = 2)] | |
out_dir: String, | |
/// extract all files | |
#[clap(short, long, takes_value = false, display_order = 3)] | |
all: bool, | |
#[clap(flatten)] | |
common: PadSubCommandCommonArgs, | |
} | |
#[derive(Debug, Args)] | |
#[clap(arg_required_else_help = true)] | |
struct PadFetch { | |
/// URL to fetch from | |
#[clap(short, long, display_order = 1)] | |
from_url: String, | |
/// Output directory | |
#[clap(short, long, display_order = 2)] | |
out_dir: String, | |
/// meta version to extract | |
#[clap(short, long, default_value = "latest", display_order = 3)] | |
version: String, | |
#[clap(flatten)] | |
common: PadSubCommandCommonArgs, | |
} | |
#[derive(Debug, Args)] | |
#[clap(arg_required_else_help = true)] | |
struct PadList { | |
/// From meta file | |
#[clap(short, long, display_order = 1)] | |
from_file: String, | |
/// Output file | |
#[clap(short, long, display_order = 2)] | |
out_file: String, | |
#[clap(flatten)] | |
common: PadSubCommandCommonArgs, | |
} | |
fn main() { | |
let cli = Cli::parse(); | |
match &cli.command { | |
Commands::Pad(pad) => { | |
if let Some(pad_cmd) = &pad.command { | |
// Just mocking, the subcommand logic would be in pad_cmd.rs | |
match pad_cmd { | |
PadCommands::Extract(extract) => { | |
if let Some(hash) = &extract.common.hash { | |
println!("Calling Extract with hash: {}", hash); | |
} else if let Some(infile) = &extract.common.infile { | |
println!("Calling Extract with infile filter: {}", infile); | |
} else { | |
let query_path = extract.common.query_path.clone().unwrap_or(".*".to_string()); | |
let query_file = extract.common.query_file.clone().unwrap_or(".*".to_string()); | |
if ".*" == query_path && ".*" == query_file { | |
println!("Calling Extract with no filter. This can take a long time!"); | |
if !extract.all { | |
println!("would ask for confirmation to continue"); | |
} | |
} else { | |
println!("Extract with path and file filter: {}, {}", query_path, query_file); | |
} | |
} | |
} | |
PadCommands::Fetch(fetch) => { | |
println!("Fetching {:?}", fetch); | |
} | |
PadCommands::List(list) => { | |
println!("Listing {:?}", list); | |
} | |
PadCommands::Changes(changes) => { | |
println!("Diffing {:?}", changes); | |
} | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment