netsky 0.2.0

netsky CLI: the viable system launcher and subcommand dispatcher
Documentation
use clap::Subcommand;

#[derive(Subcommand, Debug)]
#[command(subcommand_required = true, arg_required_else_help = true)]
pub enum EmailCommand {
    Send {
        #[arg(long)]
        from: String,
        #[arg(long)]
        to: String,
        #[arg(long)]
        subject: String,
        #[arg(long)]
        text: String,
    },
    List {
        account: String,
        #[arg(long)]
        query: String,
    },
    Read {
        id: String,
    },
    #[command(subcommand)]
    Draft(EmailDraftCommand),
    Archive {
        id: String,
    },
    Trash {
        id: String,
    },
}

#[derive(Subcommand, Debug)]
#[command(subcommand_required = true, arg_required_else_help = true)]
pub enum EmailDraftCommand {
    Create {
        #[arg(long)]
        from: String,
        #[arg(long)]
        to: String,
        #[arg(long)]
        subject: String,
        #[arg(long)]
        text: String,
        #[arg(long)]
        in_reply_to_id: Option<String>,
    },
    Send {
        id: String,
    },
    #[command(name = "ls", visible_alias = "list")]
    List {
        account: String,
    },
}

pub fn run(cmd: EmailCommand) -> netsky_core::Result<()> {
    match cmd {
        EmailCommand::Send {
            from,
            to,
            subject,
            text,
        } => {
            let id = netsky_channels::email::send::send_message(&from, &to, &subject, &text)
                .map_err(|e| netsky_core::Error::Message(e.to_string()))?;
            println!("sent: {id}");
        }
        EmailCommand::List { account, query } => {
            print_json(netsky_channels::email::receive::list_messages(
                &account, &query,
            ))?;
        }
        EmailCommand::Read { id } => {
            print_json(netsky_channels::email::receive::read_message(&id))?;
        }
        EmailCommand::Draft(EmailDraftCommand::Create {
            from,
            to,
            subject,
            text,
            in_reply_to_id,
        }) => {
            let id = netsky_channels::email::send::create_draft(
                &from,
                &to,
                &subject,
                &text,
                in_reply_to_id.as_deref(),
            )
            .map_err(|e| netsky_core::Error::Message(e.to_string()))?;
            println!("created: {id}");
        }
        EmailCommand::Draft(EmailDraftCommand::Send { id }) => {
            let msg_id = netsky_channels::email::send::send_draft(&id)
                .map_err(|e| netsky_core::Error::Message(e.to_string()))?;
            println!("sent: {msg_id}");
        }
        EmailCommand::Draft(EmailDraftCommand::List { account }) => {
            print_json(netsky_channels::email::send::list_drafts(&account))?;
        }
        EmailCommand::Archive { id } => {
            netsky_channels::email::send::archive_message(&id)
                .map_err(|e| netsky_core::Error::Message(e.to_string()))?;
            println!("archived: {id}");
        }
        EmailCommand::Trash { id } => {
            netsky_channels::email::send::trash_message(&id)
                .map_err(|e| netsky_core::Error::Message(e.to_string()))?;
            println!("trashed: {id}");
        }
    }
    Ok(())
}

fn print_json<T: serde::Serialize>(value: anyhow::Result<T>) -> netsky_core::Result<()> {
    let value = value.map_err(|e| netsky_core::Error::Message(e.to_string()))?;
    println!(
        "{}",
        serde_json::to_string_pretty(&value)
            .map_err(|e| netsky_core::Error::Message(e.to_string()))?
    );
    Ok(())
}