Skip to main content

canic_cli/
lib.rs

1pub mod snapshot;
2
3use std::ffi::OsString;
4use thiserror::Error as ThisError;
5
6///
7/// CliError
8///
9
10#[derive(Debug, ThisError)]
11pub enum CliError {
12    #[error("{0}")]
13    Usage(&'static str),
14
15    #[error(transparent)]
16    Snapshot(#[from] snapshot::SnapshotCommandError),
17}
18
19/// Run the CLI from process arguments.
20pub fn run_from_env() -> Result<(), CliError> {
21    run(std::env::args_os().skip(1))
22}
23
24/// Run the CLI from an argument iterator.
25pub fn run<I>(args: I) -> Result<(), CliError>
26where
27    I: IntoIterator<Item = OsString>,
28{
29    let mut args = args.into_iter();
30    let Some(command) = args.next().and_then(|arg| arg.into_string().ok()) else {
31        return Err(CliError::Usage(usage()));
32    };
33
34    match command.as_str() {
35        "snapshot" => snapshot::run(args).map_err(CliError::from),
36        "help" | "--help" | "-h" => {
37            println!("{}", usage());
38            Ok(())
39        }
40        _ => Err(CliError::Usage(usage())),
41    }
42}
43
44// Return the top-level usage text.
45const fn usage() -> &'static str {
46    "usage: canic snapshot download --canister <id> --out <dir> [--root <id> | --registry-json <file>] [--include-children] [--recursive] [--dry-run] [--stop-before-snapshot] [--resume-after-snapshot] [--network <name>]"
47}