ex-cli 1.21.0

Command line tool to find, filter, sort and list files.
Documentation
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)
    }
}