crystal_cif_io/grammar/strings_textfields/
double_quoted_string.rs1use std::fmt::Display;
2
3use winnow::{
4 combinator::{peek, preceded, repeat_till, terminated},
5 error::StrContext,
6 Parser,
7};
8
9use crate::grammar::{
10 character_sets::{AnyPrintChar, DoubleQuote},
11 whitespace_comments::WhiteSpace,
12 SyntacticUnit,
13};
14
15#[derive(Debug, Clone)]
16pub struct DoubleQuotedString {
17 content: String,
18}
19
20impl AsRef<str> for DoubleQuotedString {
21 #[inline]
22 fn as_ref(&self) -> &str {
23 <String as AsRef<str>>::as_ref(&self.content)
24 }
25}
26
27impl Display for DoubleQuotedString {
28 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29 write!(f, "{}", self.formatted_output())
30 }
31}
32
33impl DoubleQuotedString {
34 pub fn new(content: String) -> Self {
35 Self { content }
36 }
37}
38
39impl SyntacticUnit for DoubleQuotedString {
40 type ParseResult = Self;
41
42 type FormatOutput = String;
43
44 fn parser(input: &mut &str) -> winnow::prelude::PResult<Self::ParseResult> {
45 preceded(
46 DoubleQuote::parser.context(StrContext::Label("<single_quote> Open")),
47 repeat_till(
48 0..,
49 AnyPrintChar::parser.context(StrContext::Label(
50 "AnyPrintChar, single quote not following white space",
51 )),
52 terminated(DoubleQuote::parser, peek(WhiteSpace::parser))
53 .context(StrContext::Label("<single_quote><WhiteSpace>")),
54 )
55 .map(|(s, _open_quote): (String, DoubleQuote)| s)
56 .context(StrContext::Label("AnyPrintChar")),
57 )
59 .map(DoubleQuotedString::new)
60 .parse_next(input)
61 }
62
63 fn formatted_output(&self) -> Self::FormatOutput {
64 format!(r#""{}""#, self.content)
65 }
66}
67
68#[cfg(test)]
69mod test {
70 use super::DoubleQuotedString;
83 use crate::grammar::SyntacticUnit;
84
85 #[test]
86 fn double_quoted_string() {
87 let mut input = "\"\\f scans, and \\w scans with \\k offsets Mr. Evan\"s things\"
88";
89 match DoubleQuotedString::parser(&mut input) {
104 Ok(s) => {
106 println!("{s}");
107 dbg!(input);
108 }
109 Err(d) => {
110 dbg!(d);
111 dbg!(input);
112 }
113 }
114 }
115}