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#[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}