dysk_cli/
args.rs

1use {
2    crate::{
3        cols::Cols,
4        filter::Filter,
5        sorting::Sorting,
6        units::Units,
7    },
8    clap::{
9        Parser,
10        ValueEnum,
11    },
12    termimad::crossterm::tty::IsTty,
13};
14
15/// List your filesystems.
16///
17/// Documentation at https://dystroy.org/dysk
18#[derive(Debug, Parser)]
19#[command(
20    author,
21    about,
22    name = "dysk",
23    disable_version_flag = true,
24    version,
25    disable_help_flag = true
26)]
27pub struct Args {
28    /// print help information
29    #[arg(long)]
30    pub help: bool,
31
32    /// print the version
33    #[arg(long)]
34    pub version: bool,
35
36    /// show all mount points
37    #[arg(short, long)]
38    pub all: bool,
39
40    /// whether to have styles and colors
41    #[arg(long, default_value = "auto", value_name = "color")]
42    pub color: TriBool,
43
44    /// use only ASCII characters for table rendering
45    #[arg(long)]
46    pub ascii: bool,
47
48    /// fetch stats of remote volumes
49    #[arg(long, default_value = "auto", value_name = "choice")]
50    pub remote_stats: TriBool,
51
52    /// list the column names which can be used in -s, -f, or -c
53    #[arg(long)]
54    pub list_cols: bool,
55
56    /// columns, eg `-c +inodes` or `-c id+dev+default`
57    #[arg(
58        short,
59        long,
60        default_value = "fs+type+disk+used+use+free+size+mp",
61        value_name = "columns"
62    )]
63    pub cols: Cols,
64
65    /// filter, eg `-f '(size<35G | remote=false) & type=xfs'`
66    #[arg(short, long, value_name = "expr")]
67    pub filter: Option<Filter>,
68
69    /// sort, eg `inodes`, `type-desc`, or `size-asc`
70    #[arg(short, long, default_value = "size", value_name = "sort")]
71    pub sort: Sorting,
72
73    /// units: `SI` (SI norm), `binary` (1024 based), or `bytes` (raw number)
74    #[arg(short, long, default_value = "SI", value_name = "unit")]
75    pub units: Units,
76
77    /// output as JSON
78    #[arg(short, long)]
79    pub json: bool,
80
81    /// output as CSV
82    #[arg(long)]
83    pub csv: bool,
84
85    /// CSV separator
86    #[arg(long, default_value = ",", value_name = "sep")]
87    pub csv_separator: char,
88
89    /// if provided, only the device holding this path will be shown
90    pub path: Option<std::path::PathBuf>,
91}
92
93/// This is an Option<bool> but I didn't find any way to configure
94/// clap to parse an Option<T> as I want
95#[derive(ValueEnum, Debug, Clone, Copy, PartialEq, Eq)]
96pub enum TriBool {
97    Auto,
98    Yes,
99    No,
100}
101impl TriBool {
102    pub fn unwrap_or_else<F>(
103        self,
104        f: F,
105    ) -> bool
106    where
107        F: FnOnce() -> bool,
108    {
109        match self {
110            Self::Auto => f(),
111            Self::Yes => true,
112            Self::No => false,
113        }
114    }
115}
116
117impl Args {
118    pub fn color(&self) -> bool {
119        self.color.unwrap_or_else(|| std::io::stdout().is_tty())
120    }
121}