dysk_cli/
args.rs

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