Skip to main content

btrfs_cli/
filesystem.rs

1use crate::{Format, Runnable, util::SizeFormat};
2use anyhow::Result;
3use clap::{Args, Parser};
4
5mod commit_stats;
6mod defrag;
7mod df;
8mod du;
9mod label;
10mod mkswapfile;
11mod resize;
12mod show;
13mod sync;
14mod usage;
15
16pub use self::{
17    commit_stats::*, defrag::*, df::*, du::*, label::*, mkswapfile::*,
18    resize::*, show::*, sync::*, usage::*,
19};
20
21/// Overall filesystem tasks and information.
22///
23/// Perform filesystem-level operations including checking available space,
24/// disk usage analysis, defragmentation, resizing, labeling, and
25/// synchronization. These commands provide views into filesystem state and
26/// allow configuration of filesystem-wide settings.
27#[derive(Parser, Debug)]
28pub struct FilesystemCommand {
29    #[clap(subcommand)]
30    pub subcommand: FilesystemSubcommand,
31}
32
33impl Runnable for FilesystemCommand {
34    fn run(&self, format: Format, dry_run: bool) -> Result<()> {
35        match &self.subcommand {
36            FilesystemSubcommand::Df(cmd) => cmd.run(format, dry_run),
37            FilesystemSubcommand::Du(cmd) => cmd.run(format, dry_run),
38            FilesystemSubcommand::Show(cmd) => cmd.run(format, dry_run),
39            FilesystemSubcommand::Sync(cmd) => cmd.run(format, dry_run),
40            FilesystemSubcommand::Defragment(cmd) => cmd.run(format, dry_run),
41            FilesystemSubcommand::Resize(cmd) => cmd.run(format, dry_run),
42            FilesystemSubcommand::Label(cmd) => cmd.run(format, dry_run),
43            FilesystemSubcommand::Usage(cmd) => cmd.run(format, dry_run),
44            FilesystemSubcommand::Mkswapfile(cmd) => cmd.run(format, dry_run),
45            FilesystemSubcommand::CommitStats(cmd) => cmd.run(format, dry_run),
46        }
47    }
48}
49
50#[derive(Parser, Debug)]
51pub enum FilesystemSubcommand {
52    Df(FilesystemDfCommand),
53    Du(FilesystemDuCommand),
54    Show(FilesystemShowCommand),
55    Sync(FilesystemSyncCommand),
56    #[clap(alias = "defrag")]
57    Defragment(FilesystemDefragCommand),
58    Resize(FilesystemResizeCommand),
59    Label(FilesystemLabelCommand),
60    Usage(FilesystemUsageCommand),
61    Mkswapfile(FilesystemMkswapfileCommand),
62    CommitStats(FilesystemCommitStatsCommand),
63}
64
65/// Unit display mode flags, shared by subcommands that output sizes.
66///
67/// Control how sizes are displayed in output. By default, human-readable
68/// format with base 1024 (KiB, MiB, GiB, TiB) is used. You can specify
69/// exact units or enable base 1000 (kB, MB, GB, TB) with --si.
70#[derive(Args, Debug)]
71pub struct UnitMode {
72    /// Show raw numbers in bytes
73    #[clap(long, overrides_with_all = ["human_readable", "iec", "si", "kbytes", "mbytes", "gbytes", "tbytes"])]
74    pub raw: bool,
75
76    /// Show human-friendly numbers using base 1024 (default)
77    #[clap(long, overrides_with_all = ["raw", "iec", "si", "kbytes", "mbytes", "gbytes", "tbytes"])]
78    pub human_readable: bool,
79
80    /// Use 1024 as a base (KiB, MiB, GiB, TiB)
81    #[clap(long, overrides_with_all = ["raw", "human_readable", "si", "kbytes", "mbytes", "gbytes", "tbytes"])]
82    pub iec: bool,
83
84    /// Use 1000 as a base (kB, MB, GB, TB)
85    #[clap(long, overrides_with_all = ["raw", "human_readable", "iec", "kbytes", "mbytes", "gbytes", "tbytes"])]
86    pub si: bool,
87
88    /// Show sizes in KiB, or kB with --si
89    #[clap(long, overrides_with_all = ["raw", "human_readable", "iec", "si", "mbytes", "gbytes", "tbytes"])]
90    pub kbytes: bool,
91
92    /// Show sizes in MiB, or MB with --si
93    #[clap(long, overrides_with_all = ["raw", "human_readable", "iec", "si", "kbytes", "gbytes", "tbytes"])]
94    pub mbytes: bool,
95
96    /// Show sizes in GiB, or GB with --si
97    #[clap(long, overrides_with_all = ["raw", "human_readable", "iec", "si", "kbytes", "mbytes", "tbytes"])]
98    pub gbytes: bool,
99
100    /// Show sizes in TiB, or TB with --si
101    #[clap(long, overrides_with_all = ["raw", "human_readable", "iec", "si", "kbytes", "mbytes", "gbytes"])]
102    pub tbytes: bool,
103}
104
105impl UnitMode {
106    /// Resolve the clap flags into a `SizeFormat`.
107    pub fn resolve(&self) -> SizeFormat {
108        let si = self.si;
109        if self.raw {
110            SizeFormat::Raw
111        } else if self.kbytes {
112            SizeFormat::Fixed(if si { 1000 } else { 1024 })
113        } else if self.mbytes {
114            SizeFormat::Fixed(if si { 1_000_000 } else { 1024 * 1024 })
115        } else if self.gbytes {
116            SizeFormat::Fixed(if si {
117                1_000_000_000
118            } else {
119                1024 * 1024 * 1024
120            })
121        } else if self.tbytes {
122            SizeFormat::Fixed(if si {
123                1_000_000_000_000
124            } else {
125                1024u64.pow(4)
126            })
127        } else if si {
128            SizeFormat::HumanSi
129        } else {
130            SizeFormat::HumanIec
131        }
132    }
133}