use crate::error::{MyError, MyResult};
use indexmap::IndexSet;
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum DirKind {
Asc,
Desc,
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum OrderKind {
Dir,
Group,
Name,
Ext,
Size(DirKind),
Time(DirKind),
}
impl OrderKind {
fn from_char(ch: char) -> Option<Self> {
match ch {
'd' => Some(Self::Dir),
'n' => Some(Self::Name),
'e' => Some(Self::Ext),
's' => Some(Self::Size(DirKind::Asc)),
't' => Some(Self::Time(DirKind::Asc)),
_ => None,
}
}
pub fn ascending(self: Self) -> Self {
match self {
Self::Size(_) => Self::Size(DirKind::Asc),
Self::Time(_) => Self::Time(DirKind::Asc),
any => any,
}
}
pub fn descending(self: Self) -> Self {
match self {
Self::Size(_) => Self::Size(DirKind::Desc),
Self::Time(_) => Self::Time(DirKind::Desc),
any => any,
}
}
}
#[derive(Clone)]
pub struct OrderVec {
pub inner: Vec<OrderKind>,
}
impl OrderVec {
pub fn from_str(value: &str) -> MyResult<Self> {
let mut results = IndexSet::new();
let mut result = None;
for ch in value.chars() {
if ch.is_alphabetic() {
if let Some(result) = result {
results.insert(result);
}
result = OrderKind::from_char(ch);
if result == None {
return Err(MyError::create_clap("order", value));
}
} else if ch == '+' {
result = result.map(|x| x.ascending());
} else if ch == '-' {
result = result.map(|x| x.descending());
} else {
return Err(MyError::create_clap("order", value));
}
}
if let Some(result) = result {
results.insert(result);
}
let results = Self { inner: results.into_iter().collect() };
Ok(results)
}
}