plantuml_parser/dsl/token/
include.rs1use crate::IncludeSpecifierToken;
2use crate::{ParseContainer, ParseResult, wr, wr2};
3use nom::Parser;
4use nom::branch::alt;
5use nom::bytes::complete::tag;
6use nom::character::complete::space1;
7
8#[derive(Clone, Debug)]
55pub struct IncludeToken {
56 specifier: IncludeSpecifierToken,
57 kind: IncludeKind,
58}
59
60#[derive(Clone, Debug, PartialEq, Eq)]
62pub enum IncludeKind {
63 Include,
64 IncludeMany,
65 IncludeOnce,
66}
67
68impl IncludeToken {
69 pub fn parse(input: ParseContainer) -> ParseResult<Self> {
71 let (rest, (include, spaces, (specifier_raws, specifier))) = (
72 alt((
73 wr!(tag("!include_many")),
74 wr!(tag("!include_once")),
75 wr!(tag("!include")),
76 )),
77 wr!(space1),
78 wr2!(IncludeSpecifierToken::parse),
79 )
80 .parse(input)?;
81
82 let kind = match include.as_str() {
83 "!include" => IncludeKind::Include,
84 "!include_many" => IncludeKind::IncludeMany,
85 "!include_once" => {
86 tracing::warn!("Multiple include errors with `include_once` are not supported.");
87 IncludeKind::IncludeOnce
88 }
89
90 _ => unreachable!("IncludeToken"),
91 };
92
93 let ret0 = ParseContainer::from(vec![include, spaces, specifier_raws]);
94 let ret1 = Self { specifier, kind };
95
96 Ok((rest, (ret0, ret1)))
97 }
98
99 pub fn kind(&self) -> &IncludeKind {
101 &self.kind
102 }
103}
104
105impl std::ops::Deref for IncludeToken {
106 type Target = IncludeSpecifierToken;
107 fn deref(&self) -> &Self::Target {
108 &self.specifier
109 }
110}
111
112#[cfg(test)]
113mod tests {
114 use super::*;
115
116 #[test]
117 fn test_parse() -> anyhow::Result<()> {
118 let testdata = "!include foo.puml ";
119 let (rest, (parsed, include)) = IncludeToken::parse(testdata.into())?;
120 assert_eq!(rest, " ");
121 assert_eq!(parsed, "!include foo.puml");
122 assert_eq!(include.filepath(), "foo.puml");
123 assert!(include.id().is_none());
124 assert_eq!(include.kind(), &IncludeKind::Include);
125
126 let testdata = "!include foo.puml!bar ";
127 let (rest, (parsed, include)) = IncludeToken::parse(testdata.into())?;
128 assert_eq!(rest, " ");
129 assert_eq!(parsed, "!include foo.puml!bar");
130 assert_eq!(include.filepath(), "foo.puml");
131 assert_eq!(include.id(), Some("bar"));
132 assert_eq!(include.kind(), &IncludeKind::Include);
133
134 let testdata = "!include_many foo.puml!bar ";
135 let (rest, (parsed, include)) = IncludeToken::parse(testdata.into())?;
136 assert_eq!(rest, " ");
137 assert_eq!(parsed, "!include_many foo.puml!bar");
138 assert_eq!(include.filepath(), "foo.puml");
139 assert_eq!(include.id(), Some("bar"));
140 assert_eq!(include.kind(), &IncludeKind::IncludeMany);
141
142 let testdata = "!include_once foo.puml!bar ";
143 let (rest, (parsed, include)) = IncludeToken::parse(testdata.into())?;
144 assert_eq!(rest, " ");
145 assert_eq!(parsed, "!include_once foo.puml!bar");
146 assert_eq!(include.filepath(), "foo.puml");
147 assert_eq!(include.id(), Some("bar"));
148 assert_eq!(include.kind(), &IncludeKind::IncludeOnce);
149
150 Ok(())
151 }
152}