Skip to main content

fancy_tree/sorting/
direction.rs

1//! Module for sorting direction.
2use mlua::{FromLua, Lua};
3
4#[derive(Debug, PartialEq, Eq, Clone, Copy)]
5pub enum Direction {
6    /// Ascending order.
7    Asc,
8    /// Descending order.
9    Desc,
10}
11
12impl Direction {
13    const ASC_PREFIX: &'static str = "asc";
14    const DESC_PREFIX: &'static str = "desc";
15
16    /// Converts a string to `Self`.
17    fn from_string(s: &mlua::String) -> Option<Self> {
18        use Direction::*;
19
20        let s = s.as_bytes();
21
22        [(Self::ASC_PREFIX, Asc), (Self::DESC_PREFIX, Desc)]
23            .into_iter()
24            .find_map(|(prefix, d)| s.starts_with(prefix.as_bytes()).then_some(d))
25    }
26}
27
28impl Default for Direction {
29    #[inline]
30    fn default() -> Self {
31        Self::Asc
32    }
33}
34
35impl FromLua for Direction {
36    fn from_lua(value: mlua::Value, _lua: &Lua) -> mlua::Result<Self> {
37        let type_name = value.type_name();
38
39        let conversion_error = || mlua::Error::FromLuaConversionError {
40            from: type_name,
41            to: String::from("Direction"),
42            message: Some(format!(
43                r#"Should be either "{}" or "{}""#,
44                Self::ASC_PREFIX,
45                Self::DESC_PREFIX
46            )),
47        };
48
49        value
50            .as_string()
51            .and_then(Self::from_string)
52            .ok_or_else(conversion_error)
53    }
54}
55
56#[cfg(test)]
57mod tests {
58    use super::*;
59    use rstest::rstest;
60
61    #[rstest]
62    #[case(r#""asc""#, Direction::Asc)]
63    #[case(r#""ascending""#, Direction::Asc)]
64    #[case(r#""desc""#, Direction::Desc)]
65    #[case(r#""descending""#, Direction::Desc)]
66    fn test_from_lua(#[case] chunk: &str, #[case] expected: Direction) {
67        let lua = Lua::new();
68        let actual: Direction = lua.load(chunk).eval().unwrap();
69        assert_eq!(expected, actual);
70    }
71
72    #[test]
73    fn test_from_lua_err() {
74        let lua = Lua::new();
75        let chunk = r#"1"#;
76        assert!(lua.load(chunk).eval::<Direction>().is_err())
77    }
78}