fancy_tree/config/main/
mod.rs1use super::ConfigFile;
3use crate::color::ColorChoice;
4use crate::lua::interop;
5use crate::sorting;
6use crate::tree::Entry;
7use mlua::{
8 Either::{self, Left, Right},
9 FromLua, Lua,
10};
11use std::cmp::Ordering;
12use std::path::Path;
13
14type Sorting = Either<sorting::Sorting, mlua::Function>;
17
18#[derive(Debug)]
20pub struct Main {
21 color: ColorChoice,
23 skip: Option<mlua::Function>,
25 sorting: Sorting,
27}
28
29impl Main {
30 #[inline]
32 pub fn color_choice(&self) -> ColorChoice {
33 self.color
34 }
35 pub fn should_skip<P, F>(&self, entry: &Entry<P>, git_helper: F) -> bool
40 where
41 P: AsRef<Path>,
42 F: FnOnce() -> bool,
43 {
44 let default = entry.is_hidden() || git_helper();
45 let path = entry.path();
46 let attributes = interop::FileAttributes::from(entry);
47
48 self.skip
50 .as_ref()
51 .map_or(Ok(default), |f| f.call::<bool>((path, attributes, default)))
52 .unwrap_or(default)
53 }
54
55 pub fn cmp<L, R>(&self, left: L, right: R) -> Ordering
57 where
58 L: AsRef<Path>,
59 R: AsRef<Path>,
60 {
61 match self.sorting.as_ref() {
63 Left(sorting) => sorting.cmp(left, right),
64 Right(f) => f
65 .call((left.as_ref(), right.as_ref()))
66 .map(Self::isize_to_ordering)
67 .unwrap_or(Ordering::Equal),
68 }
69 }
70
71 fn default_sorting() -> Sorting {
73 Left(Default::default())
74 }
75
76 fn isize_to_ordering(n: isize) -> Ordering {
78 match n {
79 ..=-1 => Ordering::Less,
80 0 => Ordering::Equal,
81 1.. => Ordering::Greater,
82 }
83 }
84}
85
86impl Default for Main {
87 fn default() -> Self {
88 Self {
89 color: Default::default(),
90 skip: None,
91 sorting: Self::default_sorting(),
92 }
93 }
94}
95
96impl ConfigFile for Main {
97 const FILENAME: &'static str = "config.lua";
98 const DEFAULT_MODULE: &'static str = include_str!("./config.lua");
99}
100
101impl FromLua for Main {
102 fn from_lua(value: mlua::Value, _lua: &Lua) -> mlua::Result<Self> {
103 let type_name = value.type_name();
104
105 let conversion_error = || mlua::Error::FromLuaConversionError {
106 from: type_name,
107 to: String::from("config::Main"),
108 message: None,
109 };
110
111 let table = value.as_table().ok_or_else(conversion_error)?;
112 let color = table
113 .get::<Option<ColorChoice>>("color")?
114 .unwrap_or_default();
115 let skip: Option<mlua::Function> = table.get("skip")?;
116 let sorting = table
117 .get::<Option<Sorting>>("sorting")?
118 .unwrap_or_else(Self::default_sorting);
119 let main = Main {
120 color,
121 skip,
122 sorting,
123 };
124 Ok(main)
125 }
126}
127
128#[cfg(test)]
129mod tests {
130 use super::*;
131 use rstest::rstest;
132
133 #[rstest]
134 #[case(-1, Ordering::Less)]
135 #[case(0, Ordering::Equal)]
136 #[case(1, Ordering::Greater)]
137 fn test_isize_to_ordering(#[case] n: isize, #[case] expected: Ordering) {
138 assert_eq!(expected, Main::isize_to_ordering(n));
139 }
140}