intuicio_parser/
open_close.rs

1use crate::{ParseResult, Parser, ParserExt, ParserHandle, ParserRegistry};
2
3pub mod shorthand {
4    use super::*;
5    use crate::shorthand::ignore;
6
7    pub fn oc(parser: ParserHandle, open: ParserHandle, close: ParserHandle) -> ParserHandle {
8        OpenCloseParser::new(parser, open, close).into_handle()
9    }
10
11    pub fn prefix(parser: ParserHandle, prefix: ParserHandle) -> ParserHandle {
12        oc(parser, prefix, ignore())
13    }
14
15    pub fn suffix(parser: ParserHandle, suffix: ParserHandle) -> ParserHandle {
16        oc(parser, ignore(), suffix)
17    }
18}
19
20#[derive(Clone)]
21pub struct OpenCloseParser {
22    parser: ParserHandle,
23    open: ParserHandle,
24    close: ParserHandle,
25}
26
27impl OpenCloseParser {
28    pub fn new(parser: ParserHandle, open: ParserHandle, close: ParserHandle) -> Self {
29        Self {
30            parser,
31            open,
32            close,
33        }
34    }
35}
36
37impl Parser for OpenCloseParser {
38    fn parse<'a>(&self, registry: &ParserRegistry, mut input: &'a str) -> ParseResult<'a> {
39        let (new_input, _) = self.open.parse(registry, input)?;
40        input = new_input;
41        let (new_input, result) = self.parser.parse(registry, input)?;
42        input = new_input;
43        let (new_input, _) = self.close.parse(registry, input)?;
44        input = new_input;
45        Ok((input, result))
46    }
47
48    fn extend(&self, parser: ParserHandle) {
49        self.parser.extend(parser);
50    }
51}
52
53#[cfg(test)]
54mod tests {
55    use crate::{
56        open_close::OpenCloseParser,
57        shorthand::{lit, oc, prefix, suffix},
58        ParserRegistry,
59    };
60
61    fn is_async<T: Send + Sync>() {}
62
63    #[test]
64    fn test_open_close() {
65        is_async::<OpenCloseParser>();
66
67        let registry = ParserRegistry::default();
68        let sequence = oc(lit("foo"), lit("("), lit(")"));
69        let (rest, result) = sequence.parse(&registry, "(foo)").unwrap();
70        assert_eq!(rest, "");
71        let result = result.consume::<String>().ok().unwrap();
72        assert_eq!(result.as_str(), "foo");
73    }
74
75    #[test]
76    fn test_prefix() {
77        let registry = ParserRegistry::default();
78        let sequence = prefix(lit("foo"), lit("("));
79        let (rest, result) = sequence.parse(&registry, "(foo").unwrap();
80        assert_eq!(rest, "");
81        let result = result.consume::<String>().ok().unwrap();
82        assert_eq!(result.as_str(), "foo");
83    }
84
85    #[test]
86    fn test_suffix() {
87        let registry = ParserRegistry::default();
88        let sequence = suffix(lit("foo"), lit(")"));
89        let (rest, result) = sequence.parse(&registry, "foo)").unwrap();
90        assert_eq!(rest, "");
91        let result = result.consume::<String>().ok().unwrap();
92        assert_eq!(result.as_str(), "foo");
93    }
94}