dysk_cli/
args.rs

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