//! Command-line interface definition. use std::path::PathBuf; use clap::{Parser, Subcommand, ValueEnum}; #[derive(Parser)] #[command( name = "posta", version, about = "A tiny, generic IMAP/SMTP mail CLI", long_about = "posta — manage any IMAP/SMTP mailbox from your terminal.\n\ Accounts live in a TOML config file; every command prints JSON \ by default so it plays nicely with jq and scripts." )] pub struct Cli { /// Config file (default: $POSTA_CONFIG or ~/.config/posta/config.toml) #[arg(long, global = true, value_name = "FILE")] pub config: Option, /// Account name from the config (default: $POSTA_ACCOUNT or `default_account`) #[arg(long, short = 'a', global = true, value_name = "NAME")] pub account: Option, /// Output format #[arg(long, global = true, value_enum, default_value_t = Format::Json)] pub format: Format, #[command(subcommand)] pub cmd: Cmd, } #[derive(Clone, Copy, PartialEq, Eq, ValueEnum)] pub enum Format { Json, Table, } #[derive(Subcommand)] pub enum Cmd { /// List the accounts defined in the config file Accounts, /// List mailbox folders Folders, /// Message and unread counts for a folder Status { #[arg(long, default_value = "INBOX")] folder: String, }, /// List messages, newest first List { #[arg(long, default_value = "INBOX")] folder: String, /// Only unread messages (shorthand for --query UNSEEN) #[arg(long)] unread: bool, /// Raw IMAP SEARCH query, e.g. 'FROM bank SINCE 1-Jul-2026' #[arg(long)] query: Option, #[arg(long, default_value_t = 20)] max: usize, }, /// Show a message by UID Get { uid: u32, #[arg(long, default_value = "INBOX")] folder: String, /// Print the raw RFC 822 source #[arg(long)] raw: bool, /// Prefer the text/html part over text/plain #[arg(long)] html: bool, /// Mark the message as read after fetching it #[arg(long)] mark_read: bool, }, /// Send a message (body from --body, --body-file, or stdin) Send { #[arg(long, required = true)] to: Vec, #[arg(long)] cc: Vec, #[arg(long)] subject: String, #[arg(long)] body: Option, #[arg(long)] body_file: Option, /// Skip saving a copy to the sent folder #[arg(long)] no_record: bool, }, /// Add or remove message flags Mark { #[arg(value_enum)] state: MarkState, #[arg(required = true)] uids: Vec, #[arg(long, default_value = "INBOX")] folder: String, }, /// Move messages to another folder Move { #[arg(required = true)] uids: Vec, #[arg(long)] to: String, #[arg(long, default_value = "INBOX")] folder: String, }, /// Move messages to the trash folder Delete { #[arg(required = true)] uids: Vec, #[arg(long, default_value = "INBOX")] folder: String, }, /// Run an IMAP SEARCH query and print matching UIDs Search { query: String, #[arg(long, default_value = "INBOX")] folder: String, }, } #[derive(Clone, Copy, ValueEnum)] pub enum MarkState { Read, Unread, Flagged, Unflagged, }