dysk_cli/
sorting.rs

1use {
2    crate::{
3        col::Col,
4        order::Order,
5    },
6    lfs_core::Mount,
7    std::{
8        error,
9        fmt,
10        str::FromStr,
11    },
12};
13
14/// Sorting directive: the column and the order (asc or desc)
15#[derive(Debug, Clone, Copy, PartialEq)]
16pub struct Sorting {
17    col: Col,
18    order: Order,
19}
20
21impl Default for Sorting {
22    fn default() -> Self {
23        let col = Col::default_sort_col();
24        let order = col.default_sort_order();
25        Self { col, order }
26    }
27}
28
29impl Sorting {
30    pub fn sort(
31        self,
32        mounts: &mut [Mount],
33    ) {
34        let comparator = self.col.comparator();
35        mounts.sort_by(comparator);
36        if self.order == Order::Desc {
37            mounts.reverse();
38        }
39    }
40}
41
42#[derive(Debug)]
43pub struct ParseSortingError {
44    raw: String,
45    reason: String,
46}
47impl ParseSortingError {
48    pub fn new<S: Into<String>, E: ToString>(
49        raw: S,
50        reason: E,
51    ) -> Self {
52        Self {
53            raw: raw.into(),
54            reason: reason.to_string(),
55        }
56    }
57}
58impl fmt::Display for ParseSortingError {
59    fn fmt(
60        &self,
61        f: &mut fmt::Formatter<'_>,
62    ) -> fmt::Result {
63        write!(
64            f,
65            "{:?} can't be parsed as a sort expression because {}",
66            self.raw, self.reason
67        )
68    }
69}
70impl error::Error for ParseSortingError {}
71
72impl FromStr for Sorting {
73    type Err = ParseSortingError;
74    fn from_str(s: &str) -> Result<Self, ParseSortingError> {
75        let cut_idx_len = s
76            .char_indices()
77            .find(|(_idx, c)| c.is_whitespace() || *c == '-')
78            .map(|(idx, c)| (idx, c.len_utf8()));
79        let (s_col, s_order) = match cut_idx_len {
80            Some((idx, len)) => (&s[..idx], Some(&s[idx + len..])),
81            None => (s, None),
82        };
83        let col: Col = s_col
84            .parse()
85            .map_err(|pce| ParseSortingError::new(s, Box::new(pce)))?;
86        let order = match s_order {
87            Some(s_order) => s_order
88                .parse()
89                .map_err(|poe| ParseSortingError::new(s, Box::new(poe)))?,
90            None => col.default_sort_order(),
91        };
92        Ok(Self { col, order })
93    }
94}