dialogue_rs/script/
element.rs

1//! # Top-level elements
2//!
3//! A top-level element in a script. Either a [Block], [Line], or [Comment].
4
5use super::{block::Block, command::Command, comment::Comment, line::Line, marker::Marker};
6use std::fmt;
7
8/// A top-level element in a script. Either a [Block], [Line], or [Comment].
9#[derive(Debug, PartialEq, Eq, Clone)]
10pub enum TopLevelElement {
11    /// A [Block].
12    Block(Block),
13    /// A [Line].
14    Line(Line),
15    /// A [Comment].
16    Comment(Comment),
17}
18
19impl fmt::Display for TopLevelElement {
20    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21        match self {
22            Self::Block(block) => write!(f, "{block}"),
23            Self::Line(line) => write!(f, "{line}"),
24            Self::Comment(comment) => write!(f, "{comment}"),
25        }
26    }
27}
28
29impl From<Line> for TopLevelElement {
30    fn from(line: Line) -> Self {
31        Self::Line(line)
32    }
33}
34
35impl From<Block> for TopLevelElement {
36    fn from(block: Block) -> Self {
37        Self::Block(block)
38    }
39}
40
41impl From<Comment> for TopLevelElement {
42    fn from(comment: Comment) -> Self {
43        Self::Comment(comment)
44    }
45}
46
47impl From<Marker> for TopLevelElement {
48    fn from(marker: Marker) -> Self {
49        Self::Line(Line::Marker(marker))
50    }
51}
52
53impl From<Command> for TopLevelElement {
54    fn from(command: Command) -> Self {
55        Self::Line(Line::Command(command))
56    }
57}
58
59#[cfg(test)]
60mod tests {
61    use super::TopLevelElement;
62    use crate::script::{block::Block, comment::Comment, line::Line};
63    use pretty_assertions::assert_eq;
64
65    #[test]
66    fn test_comment_round_trip() {
67        let input = "// hello\n";
68        let comment: TopLevelElement = Comment::parse(input).unwrap().into();
69        let actual = comment.to_string();
70
71        assert_eq!(input, actual);
72    }
73
74    #[test]
75    fn test_line_round_trip() {
76        let input = "|CHOICE| do the thing\n";
77        let line: TopLevelElement = Line::parse(input).unwrap().into();
78        let actual = line.to_string();
79
80        assert_eq!(input, actual);
81    }
82
83    #[test]
84    fn test_block_round_trip_with_single_line() {
85        let input = "    |CHOICE| do the thing\n";
86        let block: TopLevelElement = Block::parse(input).unwrap().into();
87        let actual = block.to_string();
88
89        assert_eq!(input, actual);
90    }
91
92    #[test]
93    fn test_block_round_trip_with_multiple_lines_1() {
94        let input = "    |TEST| A1
95        |TEST| B1
96            |TEST| C1
97        |TEST| B2
98";
99        let block: TopLevelElement = Block::parse(input).unwrap().into();
100        let actual = block.to_string();
101
102        assert_eq!(input, actual);
103    }
104
105    #[test]
106    fn test_block_round_trip_with_multiple_lines_2() {
107        let input = "    |TEST| A
108        |TEST| B
109        |TEST| C
110";
111        let block: TopLevelElement = Block::parse(input).unwrap().into();
112        let actual = block.to_string();
113
114        assert_eq!(input, actual);
115    }
116}