daisychain/cookbook/
ch_3_binding_vars.rs1use crate::prelude::*;
2
3#[derive(PartialEq, Debug)]
4struct QuotedText {
5 quote: char,
6 text: String,
7}
8
9impl QuotedText {
10 fn new(quote: char, text: String) -> Self {
11 Self { quote, text }
12 }
13}
14
15fn parse_quoted_text(inp: &str) -> Result<(&str, QuotedText), ParsingError> {
19 let (c, quote) = Cursor::from(inp)
21 .chars_in(1..=1, &['"', '\''])
22 .parse_selection()
23 .validate()?;
24
25 let (c, text) = Cursor::from(c)
27 .chars_not_in(0.., &[quote])
28 .parse_selection()
29 .chars_in(1..=1, &[quote])
30 .validate()?;
31 Ok((c, QuotedText { quote, text }))
32}
33
34fn parse_quoted_text_v2(inp: &str) -> Result<(&str, QuotedText), ParsingError> {
37 let mut quote = char::default();
38 let (c, text) = Cursor::from(inp)
39 .chars_in(1..=1, &['"', '\''])
40 .parse_selection()
41 .bind(&mut quote) .chars_not_in(0.., &[quote])
43 .parse_selection()
44 .chars_in(1..=1, &[quote])
45 .validate()?;
46 Ok((c, QuotedText { quote, text }))
47}
48
49#[cfg(test)]
50mod tests {
51 use super::*;
52 use test_log::test;
53
54 #[test]
55 fn test_parse_quoted_text() -> Result<(), ParsingError> {
56 let s = "'Hello World!', said Ferris";
57 let (c, qt) = parse_quoted_text(s)?;
58 assert_eq!(qt, QuotedText::new('\'', "Hello World!".to_string()));
59 assert_eq!(c, ", said Ferris");
60
61 let (c, qt) = parse_quoted_text("\"Hi\", he said")?;
62 assert_eq!(qt, QuotedText::new('"', "Hi".to_string()));
63 assert_eq!(c, ", he said");
64
65 let (c, qt) = parse_quoted_text_v2("\"Hi\", he said")?;
66 assert_eq!(qt, QuotedText::new('"', "Hi".to_string()));
67 assert_eq!(c, ", he said");
68
69 let res = parse_quoted_text("'Hi, ");
70 assert!(res.is_err());
71 Ok(())
72 }
73}