synd_term/cli/
mod.rs

1use std::{path::PathBuf, time::Duration};
2
3use clap::{Parser, Subcommand};
4use serde::{Deserialize, Serialize};
5use url::Url;
6
7use crate::{config, ui::theme};
8
9mod command;
10mod port;
11
12#[derive(Copy, Clone, PartialEq, Eq, Debug, clap::ValueEnum, Serialize, Deserialize)]
13#[serde(rename_all(deserialize = "kebab-case"))]
14pub enum Palette {
15    Dracula,
16    Eldritch,
17    Ferra,
18    SolarizedDark,
19    Helix,
20}
21
22impl From<Palette> for theme::Palette {
23    fn from(p: Palette) -> Self {
24        match p {
25            Palette::Dracula => theme::Palette::dracula(),
26            Palette::Eldritch => theme::Palette::eldritch(),
27            Palette::Ferra => theme::Palette::ferra(),
28            Palette::SolarizedDark => theme::Palette::solarized_dark(),
29            Palette::Helix => theme::Palette::helix(),
30        }
31    }
32}
33
34#[derive(Parser, Debug)]
35#[command(version, propagate_version = true, name = "synd")]
36pub struct Args {
37    /// Configuration file path
38    #[arg(long, short = 'c', env = config::env::CONFIG_FILE)]
39    pub config: Option<PathBuf>,
40    /// Log file path
41    #[arg(long, env = config::env::LOG_FILE)]
42    pub log: Option<PathBuf>,
43    /// Cache directory
44    #[arg(long, env = config::env::CACHE_DIR)]
45    pub cache_dir: Option<PathBuf>,
46    /// Color theme
47    #[arg(value_enum, long = "theme", env = config::env::THEME, value_name = "THEME")]
48    pub palette: Option<Palette>,
49    #[command(subcommand)]
50    pub command: Option<Command>,
51    #[command(flatten)]
52    pub api: ApiOptions,
53    #[command(flatten)]
54    pub feed: FeedOptions,
55    #[command(flatten)]
56    pub github: GithubOptions,
57    #[arg(hide = true, long = "dry-run", hide_long_help = true)]
58    pub dry_run: bool,
59}
60
61#[derive(clap::Args, Debug)]
62#[command(next_help_heading = "Api options")]
63pub struct ApiOptions {
64    /// `synd_api` endpoint
65    #[arg(long, global = true, env = config::env::ENDPOINT)]
66    pub endpoint: Option<Url>,
67    /// Client timeout(ex. 30s)
68    #[arg(long, value_parser = config::parse::flag::parse_duration_opt, env = config::env::CLIENT_TIMEOUT)]
69    pub client_timeout: Option<Duration>,
70}
71
72#[derive(clap::Args, Debug)]
73#[command(next_help_heading = "Feed options")]
74pub struct FeedOptions {
75    /// Feed entries limit to fetch
76    #[arg(long, aliases = ["max-entries"], env = config::env::FEED_ENTRIES_LIMIT)]
77    pub entries_limit: Option<usize>,
78    /// Browser command to open feed entry
79    #[arg(long, env = config::env::FEED_BROWSER)]
80    pub browser: Option<PathBuf>,
81    /// Args for launching the browser command
82    #[arg(long, env = config::env::FEED_BROWSER_ARGS)]
83    pub browser_args: Option<Vec<String>>,
84}
85
86#[derive(clap::Args, Debug)]
87#[command(next_help_heading = "GitHub options")]
88pub struct GithubOptions {
89    /// Enable GitHub notification feature
90    #[arg(
91        long,
92        short = 'G',
93        visible_alias = "enable-gh",
94        env = config::env::ENABLE_GITHUB,
95    )]
96    pub enable_github_notification: Option<bool>,
97    /// GitHub personal access token to fetch notifications
98    #[arg(
99        long,
100        env = config::env::GITHUB_PAT,
101        hide_env_values = true,
102    )]
103    pub github_pat: Option<String>,
104}
105
106#[derive(Subcommand, Debug)]
107pub enum Command {
108    #[command(alias = "clear")]
109    Clean(command::clean::CleanCommand),
110    Check(command::check::CheckCommand),
111    Export(command::export::ExportCommand),
112    Import(command::import::ImportCommand),
113    Config(command::config::ConfigCommand),
114}
115
116pub fn parse() -> Args {
117    Args::parse()
118}