dialogue_rs/script/
comment.rs1use crate::script::parser::{Parser, Rule};
10use anyhow::bail;
11use pest::iterators::Pair;
12use pest::Parser as PestParser;
13use std::fmt;
14
15#[derive(Debug, PartialEq, Eq, Clone)]
17pub struct Comment {
18 text: String,
19}
20
21impl fmt::Display for Comment {
22 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23 writeln!(f, "// {}", self.text)
24 }
25}
26
27impl Comment {
28 pub fn new(text: String) -> Self {
30 Self { text }
31 }
32
33 pub fn parse(comment_str: &str) -> Result<Self, anyhow::Error> {
35 let mut pairs = Parser::parse(Rule::Comment, comment_str)?;
36 let pair = pairs.next().expect("a pair exists");
37 assert_eq!(pairs.next(), None);
38
39 pair.try_into()
40 }
41}
42
43impl TryFrom<Pair<'_, Rule>> for Comment {
44 type Error = anyhow::Error;
45
46 fn try_from(pair: Pair<'_, Rule>) -> Result<Self, Self::Error> {
47 match pair.as_rule() {
48 Rule::Comment => {
49 let mut inner_pairs = pair.into_inner();
50 let pair = inner_pairs.next().expect("a pair exists");
51 assert!(inner_pairs.next().is_none(), "no other pairs exist");
52 let text = pair.as_str().trim().to_owned();
53
54 Ok(Self::new(text))
55 }
56 _ => bail!("Pair is not a comment: {:#?}", pair),
57 }
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use super::Comment;
64
65 #[test]
66 fn test_comment_parse() {
67 let comment = Comment::parse("// This is a comment\n").unwrap();
68 assert_eq!(comment.text, "This is a comment");
69 }
70
71 #[test]
72 fn test_round_trip() {
73 let input = "// This is a comment\n";
74 let output = Comment::parse(input).unwrap().to_string();
75 assert_eq!(input, output);
76 }
77}