use crate::{OPT_INODES, OPT_OUTPUT, OPT_PRINT_TYPE};
use clap::{parser::ValueSource, ArgMatches};
#[derive(PartialEq, Copy, Clone)]
pub(crate) enum Column {
Source,
Size,
Used,
Avail,
Pcent,
Target,
Itotal,
Iused,
Iavail,
Ipcent,
File,
Fstype,
#[cfg(target_os = "macos")]
Capacity,
}
#[derive(Debug)]
pub(crate) enum ColumnError {
MultipleColumns(String),
}
impl Column {
pub(crate) fn from_matches(matches: &ArgMatches) -> Result<Vec<Self>, ColumnError> {
match (
matches.get_flag(OPT_PRINT_TYPE),
matches.get_flag(OPT_INODES),
matches.value_source(OPT_OUTPUT) == Some(ValueSource::CommandLine),
) {
(false, false, false) => Ok(vec![
Self::Source,
Self::Size,
Self::Used,
Self::Avail,
#[cfg(target_os = "macos")]
Self::Capacity,
Self::Pcent,
Self::Target,
]),
(false, false, true) => {
let names = matches
.get_many::<String>(OPT_OUTPUT)
.unwrap()
.map(|s| s.as_str());
let mut seen: Vec<&str> = vec![];
let mut columns = vec![];
for name in names {
if seen.contains(&name) {
return Err(ColumnError::MultipleColumns(name.to_string()));
}
seen.push(name);
let column = Self::parse(name).unwrap();
columns.push(column);
}
Ok(columns)
}
(false, true, false) => Ok(vec![
Self::Source,
Self::Itotal,
Self::Iused,
Self::Iavail,
Self::Ipcent,
Self::Target,
]),
(true, false, false) => Ok(vec![
Self::Source,
Self::Fstype,
Self::Size,
Self::Used,
Self::Avail,
#[cfg(target_os = "macos")]
Self::Capacity,
Self::Pcent,
Self::Target,
]),
(true, true, false) => Ok(vec![
Self::Source,
Self::Fstype,
Self::Itotal,
Self::Iused,
Self::Iavail,
Self::Ipcent,
Self::Target,
]),
_ => unreachable!(),
}
}
fn parse(s: &str) -> Result<Self, ()> {
match s {
"source" => Ok(Self::Source),
"fstype" => Ok(Self::Fstype),
"itotal" => Ok(Self::Itotal),
"iused" => Ok(Self::Iused),
"iavail" => Ok(Self::Iavail),
"ipcent" => Ok(Self::Ipcent),
"size" => Ok(Self::Size),
"used" => Ok(Self::Used),
"avail" => Ok(Self::Avail),
"pcent" => Ok(Self::Pcent),
"file" => Ok(Self::File),
"target" => Ok(Self::Target),
_ => Err(()),
}
}
pub(crate) fn alignment(column: &Self) -> Alignment {
match column {
Self::Source | Self::Target | Self::File | Self::Fstype => Alignment::Left,
_ => Alignment::Right,
}
}
pub(crate) fn min_width(column: &Self) -> usize {
match column {
Self::Source => 14,
Self::Used => 5,
Self::Size => 5,
_ => 4,
}
}
}
pub(crate) enum Alignment {
Left,
Right,
}