ownrs/
directive.rs

1use crate::{
2    error::NomResult,
3    is_whitespace,
4    owner::{owner, Owner},
5};
6use nom::{
7    branch::alt,
8    bytes::complete::{tag, take_till1},
9    character::complete::{char, multispace0, multispace1},
10    combinator::map,
11    error::context,
12    sequence::{pair, preceded, separated_pair},
13};
14use std::path::PathBuf;
15
16#[derive(Debug, Clone, PartialEq, Eq)]
17pub enum Directive {
18    NoParent,
19    StarGlob,
20    FilePath(PathBuf),
21    Owner(Owner),
22}
23
24pub(crate) fn directive(input: &str) -> NomResult<Directive> {
25    let star_glob = char('*');
26    let no_parent = separated_pair(tag("set"), multispace1, tag("noparent"));
27    let file_path = preceded(pair(tag("file:"), multispace0), take_till1(is_whitespace));
28
29    context(
30        "directive",
31        alt((
32            map(star_glob, |_| Directive::StarGlob),
33            map(no_parent, |_| Directive::NoParent),
34            map(file_path, |path: &str| Directive::FilePath(path.into())),
35            map(owner, Directive::Owner),
36        )),
37    )(input)
38}
39
40#[cfg(test)]
41mod tests {
42    use super::*;
43
44    #[test]
45    fn star() {
46        let (rem, parsed) = directive("*").unwrap();
47
48        assert_eq!(parsed, Directive::StarGlob);
49        assert!(rem.is_empty());
50    }
51
52    #[test]
53    fn no_parent() {
54        let (rem, parsed) = directive("set noparent").unwrap();
55
56        assert_eq!(parsed, Directive::NoParent);
57        assert!(rem.is_empty());
58    }
59
60    #[test]
61    fn no_parent_ws() {
62        let (rem, parsed) = directive("set   noparent").unwrap();
63
64        assert_eq!(parsed, Directive::NoParent);
65        assert!(rem.is_empty());
66    }
67
68    #[test]
69    fn filepath_absolute() {
70        let (rem, parsed) = directive("file: /absolute/path").unwrap();
71
72        assert_eq!(parsed, Directive::FilePath("/absolute/path".into()));
73        assert!(rem.is_empty());
74    }
75
76    #[test]
77    fn filepath_relative() {
78        let (rem, parsed) = directive("file: ../relative/path").unwrap();
79
80        assert_eq!(parsed, Directive::FilePath("../relative/path".into()));
81        assert!(rem.is_empty());
82    }
83
84    #[test]
85    fn filepath_ws() {
86        let (rem, parsed) = directive("file:   /absolute/path").unwrap();
87
88        assert_eq!(parsed, Directive::FilePath("/absolute/path".into()));
89        assert!(rem.is_empty());
90    }
91
92    #[test]
93    fn owner() {
94        let (rem, parsed) = directive("owner").unwrap();
95
96        assert_eq!(parsed, Directive::Owner(Owner::Text("owner".into())));
97        assert!(rem.is_empty());
98    }
99}