static_graph/parser/
literal.rs1use std::ops::Deref;
2
3use nom::{
4 branch::alt,
5 bytes::complete::{escaped, tag},
6 character::complete::{none_of, one_of},
7 combinator::map,
8 sequence::delimited,
9 IResult,
10};
11
12use super::Parser;
13
14#[derive(Debug, Clone)]
15pub struct Literal(pub String);
16
17impl Deref for Literal {
18 type Target = str;
19 fn deref(&self) -> &str {
20 &self.0
21 }
22}
23
24impl<'a> Parser<'a> for Literal {
25 fn parse(input: &'a str) -> IResult<&'a str, Literal> {
26 alt((
27 map(single_quote, |x| Literal(x.into())),
28 map(double_quote, |x| Literal(x.into())),
29 ))(input)
30 }
31}
32
33fn single_quote(input: &str) -> IResult<&str, &str> {
34 let esc = escaped(none_of(r#"\'"#), '\\', one_of(r#"'"n\"#));
35 let esc_or_empty = alt((esc, tag("")));
36 let res = delimited(tag("\'"), esc_or_empty, tag("\'"))(input)?;
37
38 Ok(res)
39}
40
41fn double_quote(input: &str) -> IResult<&str, &str> {
42 let esc = escaped(none_of(r#"\""#), '\\', one_of(r#"'"n\"#));
43 let esc_or_empty = alt((esc, tag("")));
44 let res = delimited(tag("\""), esc_or_empty, tag("\""))(input)?;
45
46 Ok(res)
47}
48
49#[cfg(test)]
50mod tests {
51 use super::*;
52
53 #[test]
54 fn test_literal() {
55 let input = r#""foo""#;
56 match super::Literal::parse(input) {
57 Ok((remain, lit)) => {
58 assert_eq!(remain, "");
59 assert_eq!(lit.0, "foo");
60 }
61 Err(e) => panic!("Error: {e:?}"),
62 }
63 }
64}