hande 1.0.0

HANDE, Let's Go!, is a powerful bookmark manager to keep track of your favorites both on the filesystem and the web.
//! The direct command-line client: `hande claude` opens the `claude` bookmark,
//! `hande -k` lists shortcut keys, and so on. This is a thin `clap` wrapper --
//! all the actual bookmark resolution lives in `hande-api`.

use clap::{ArgGroup, Parser};
use hande_api::{Api, RawArgs};

#[derive(Parser)]
#[command(version, about)]
#[clap(group(ArgGroup::new("info").required(false).args(&["keyglobal", "keycategory", "name", "edit", "summary", "config", "delete", "rename", "list_local", "list_global", "delete_bookmark", "delete_global_bookmark", "import_bookmarks", "export_bookmarks"])))]
pub struct Cli {
    /// The bookmark name to launch
    pub name: Option<Vec<String>>,

    /// The category to use for this session
    #[arg(short, long, group = "cats")]
    pub category: Option<String>,

    ///  Get a quick summary of hande special bookmark
    #[arg(short = '0', long = "summary", default_value_t = false)]
    pub summary: bool,

    /// Edit the bookmark file
    #[arg(short, long = "edit-bookmarks", default_value_t = false)]
    pub edit: bool,

    /// Edit the configuration file
    #[arg(short = 'E', long = "edit-configuration", default_value_t = false)]
    pub config: bool,

    /// List global shortcut keys
    #[arg(short = 'K', long = "list-global-keys", default_value_t = false)]
    pub keyglobal: bool,

    /// List category keys
    #[arg(short, long = "list-category-keys", default_value_t = false)]
    pub keycategory: bool,

    /// List bookmarks in the working category
    #[arg(short = 'L', long = "list", default_value_t = false)]
    pub list_local: bool,

    /// List bookmarks in the global scope
    #[arg(short = 'G', long = "list-global", default_value_t = false)]
    pub list_global: bool,

    /// Add new category
    #[arg(short, long = "new-category", group = "cats", value_name = "CATEGORY")]
    pub new: Option<String>,

    /// Delete category from database
    #[arg(
        short,
        long = "delete-category",
        group = "cats",
        value_name = "CATEGORY"
    )]
    pub delete: Option<String>,

    /// Rename category
    #[arg(
        short,
        long = "rename-category",
        value_delimiter = ' ',
        num_args = 2,
        group = "cats",
        value_names = ["OLD_NAME", "NEW_NAME"]
    )]
    pub rename: Option<Vec<String>>,

    /// Delete a bookmark from a category
    #[arg(long = "delete-bookmark", value_name = "NAME")]
    pub delete_bookmark: Option<String>,

    /// Delete a global bookmark, wherever it physically lives
    #[arg(long = "delete-global-bookmark", value_name = "NAME")]
    pub delete_global_bookmark: Option<String>,

    /// Import bookmarks from a browser's exported HTML file (Firefox, Chrome, Safari, Edge)
    #[arg(long = "import-bookmarks", value_name = "PATH")]
    pub import_bookmarks: Option<String>,

    /// With --import-bookmarks, turn each folder into a nested subcategory instead of flattening
    #[arg(long = "preserve-folders", default_value_t = false)]
    pub preserve_folders: bool,

    /// Export bookmarks as an HTML file a browser can import
    #[arg(long = "export-bookmarks", value_name = "PATH")]
    pub export_bookmarks: Option<String>,
}

impl From<Cli> for RawArgs {
    fn from(cli: Cli) -> Self {
        Self {
            name: cli.name,
            category: cli.category,
            summary: cli.summary,
            edit: cli.edit,
            config: cli.config,
            keyglobal: cli.keyglobal,
            keycategory: cli.keycategory,
            list_local: cli.list_local,
            list_global: cli.list_global,
            new: cli.new,
            delete: cli.delete,
            rename: cli.rename,
            delete_bookmark: cli.delete_bookmark,
            delete_global_bookmark: cli.delete_global_bookmark,
            import_bookmarks: cli.import_bookmarks,
            preserve_folders: cli.preserve_folders,
            export_bookmarks: cli.export_bookmarks,
        }
    }
}

/// Parse `argv` as hande's direct CLI syntax and carry it out.
pub fn run() {
    let cli = Cli::parse();
    Api::dispatch(cli.into());
}