use chrono::NaiveDate;
use clap::{Args, Parser, Subcommand, ValueEnum};
use note_to_self_lib::Priority;
use std::path::PathBuf;
#[derive(Debug, Parser)]
#[command(name = "note", about = "Encrypted local-first journaling")]
pub struct Cli {
#[arg(short = 'j', long = "journal", global = true)]
pub journal: Option<String>,
#[arg(long = "img", value_name = "PATH", global = true)]
pub images: Vec<PathBuf>,
#[command(subcommand)]
pub command: Option<Command>,
#[arg(
value_name = "TEXT",
trailing_var_arg = true,
allow_hyphen_values = true
)]
pub text: Vec<String>,
}
#[derive(Debug, Subcommand)]
pub enum Command {
New(NewArgs),
List(ListArgs),
Edit {
id: String,
},
Delete(DeleteArgs),
Search(SearchArgs),
#[command(
alias = "browse",
alias = "tui",
about = "Browse journal entries in a terminal reader"
)]
Read(ReadArgs),
Todo(TodoArgs),
Journal {
#[command(subcommand)]
command: JournalCommand,
},
Init(InitArgs),
Deinit(DeinitArgs),
Login(AuthArgs),
Config(ConfigArgs),
Export(ExportArgs),
Import {
file: PathBuf,
},
}
#[derive(Debug, Args)]
pub struct NewArgs {
#[arg(long = "img", value_name = "PATH")]
pub images: Vec<PathBuf>,
#[arg(value_name = "TEXT", trailing_var_arg = true)]
pub text: Vec<String>,
#[arg(short = 't', long = "tag")]
pub tags: Vec<String>,
#[arg(long = "star")]
pub starred: bool,
}
#[derive(Debug, Args)]
pub struct ListArgs {
#[arg(long)]
pub today: bool,
#[arg(long)]
pub from: Option<NaiveDate>,
#[arg(long)]
pub to: Option<NaiveDate>,
#[arg(long = "tag")]
pub tag: Option<String>,
#[arg(long)]
pub starred: bool,
#[arg(short = 'n', default_value_t = 20)]
pub limit: usize,
}
#[derive(Debug, Args)]
pub struct DeleteArgs {
pub id: String,
#[arg(short = 'y', long)]
pub yes: bool,
}
#[derive(Debug, Args)]
pub struct SearchArgs {
pub query: String,
#[arg(short = 'n', default_value_t = 10)]
pub limit: usize,
}
#[derive(Debug, Args)]
pub struct ReadArgs {
#[arg(long, value_name = "YYYY-MM-DD", help = "Start the reader on this day")]
pub date: Option<NaiveDate>,
}
#[derive(Debug, Args)]
pub struct TodoArgs {
#[arg(value_name = "TEXT", num_args = 0..)]
pub text: Vec<String>,
#[arg(short = 'p', long = "priority", default_value = "medium")]
pub priority: PriorityArg,
#[arg(long)]
pub due: Option<NaiveDate>,
#[arg(short = 't', long = "tag")]
pub tags: Vec<String>,
}
#[derive(Debug, Clone, Copy, ValueEnum)]
pub enum PriorityArg {
Low,
Medium,
High,
Urgent,
}
impl From<PriorityArg> for Priority {
fn from(value: PriorityArg) -> Self {
match value {
PriorityArg::Low => Priority::Low,
PriorityArg::Medium => Priority::Medium,
PriorityArg::High => Priority::High,
PriorityArg::Urgent => Priority::Urgent,
}
}
}
#[derive(Debug, Subcommand)]
pub enum JournalCommand {
List,
New {
name: String,
#[arg(long, visible_alias = "encrypted", conflicts_with = "plain")]
locked: bool,
#[arg(long, conflicts_with = "locked")]
plain: bool,
},
Default {
name: Option<String>,
},
Lock {
name: String,
},
Unlock {
name: String,
},
Password {
#[command(subcommand)]
command: JournalPasswordCommand,
},
Delete {
name: String,
#[arg(short = 'y', long)]
yes: bool,
},
}
#[derive(Debug, Subcommand)]
pub enum JournalPasswordCommand {
#[command(alias = "set")]
Add {
name: String,
},
Change {
name: String,
},
#[command(alias = "delete", alias = "rm")]
Remove {
name: String,
},
}
#[derive(Debug, Args)]
pub struct InitArgs {
#[arg(long, conflicts_with = "server")]
pub local: bool,
#[arg(long)]
pub server: Option<String>,
#[arg(long)]
pub username: Option<String>,
#[arg(long)]
pub journal: Option<String>,
}
#[derive(Debug, Args)]
pub struct DeinitArgs {
#[arg(short = 'y', long)]
pub yes: bool,
}
#[derive(Debug, Args)]
pub struct AuthArgs {
#[arg(long)]
pub server: Option<String>,
#[arg(long)]
pub username: Option<String>,
}
#[derive(Debug, Args)]
pub struct ConfigArgs {
#[arg(long, conflicts_with = "edit")]
pub show: bool,
#[arg(long)]
pub edit: bool,
}
#[derive(Debug, Args)]
pub struct ExportArgs {
#[arg(short = 'o', long)]
pub output: Option<PathBuf>,
#[arg(long, default_value = "json")]
pub format: String,
}
pub fn joined_text(parts: &[String]) -> String {
parts.join(" ").trim().to_string()
}