1use std::collections::HashMap;
7use std::fmt;
8
9use super::error::*;
10use super::parser::*;
11use super::stmt::*;
12
13lazy_static! {
15 pub static ref STMT_PARSER: HashMap<Keyword, StmtParserFn> = {
16 let mut m = HashMap::new();
17
18 m.insert("module", ModuleStmt::parse as StmtParserFn);
19 m.insert("submodule", SubmoduleStmt::parse as StmtParserFn);
20 m.insert("yang-version", YangVersionStmt::parse as StmtParserFn);
21 m.insert("import", ImportStmt::parse as StmtParserFn);
22 m.insert("include", IncludeStmt::parse as StmtParserFn);
23 m.insert("namespace", NamespaceStmt::parse as StmtParserFn);
24 m.insert("belongs-to", BelongsToStmt::parse as StmtParserFn);
25 m.insert("prefix", PrefixStmt::parse as StmtParserFn);
26 m.insert("organization", OrganizationStmt::parse as StmtParserFn);
27 m.insert("contact", ContactStmt::parse as StmtParserFn);
28 m.insert("description", DescriptionStmt::parse as StmtParserFn);
29 m.insert("reference", ReferenceStmt::parse as StmtParserFn);
30 m.insert("units", UnitsStmt::parse as StmtParserFn);
31 m.insert("revision", RevisionStmt::parse as StmtParserFn);
32 m.insert("revision-date", RevisionDateStmt::parse as StmtParserFn);
33 m.insert("extension", ExtensionStmt::parse as StmtParserFn);
34 m.insert("argument", ArgumentStmt::parse as StmtParserFn);
35 m.insert("yin-element", YinElementStmt::parse as StmtParserFn);
36 m.insert("identity", IdentityStmt::parse as StmtParserFn);
37 m.insert("base", BaseStmt::parse as StmtParserFn);
38 m.insert("feature", FeatureStmt::parse as StmtParserFn);
39 m.insert("if-feature", IfFeatureStmt::parse as StmtParserFn);
40 m.insert("typedef", TypedefStmt::parse as StmtParserFn);
41 m.insert("type", TypeStmt::parse as StmtParserFn);
42 m.insert("range", RangeStmt::parse as StmtParserFn);
43 m.insert("fraction-digits", FractionDigitsStmt::parse as StmtParserFn);
44 m.insert("length", LengthStmt::parse as StmtParserFn);
45 m.insert("pattern", PatternStmt::parse as StmtParserFn);
46 m.insert("modifier", ModifierStmt::parse as StmtParserFn);
47 m.insert("default", DefaultStmt::parse as StmtParserFn);
48 m.insert("enum", EnumStmt::parse as StmtParserFn);
49 m.insert("path", PathStmt::parse as StmtParserFn);
50 m.insert(
51 "require-instance",
52 RequireInstanceStmt::parse as StmtParserFn,
53 );
54 m.insert("bit", BitStmt::parse as StmtParserFn);
55 m.insert("position", PositionStmt::parse as StmtParserFn);
56 m.insert("status", StatusStmt::parse as StmtParserFn);
57 m.insert("config", ConfigStmt::parse as StmtParserFn);
58 m.insert("mandatory", MandatoryStmt::parse as StmtParserFn);
59 m.insert("presence", PresenceStmt::parse as StmtParserFn);
60 m.insert("ordered-by", OrderedByStmt::parse as StmtParserFn);
61 m.insert("must", MustStmt::parse as StmtParserFn);
62 m.insert("error-message", ErrorMessageStmt::parse as StmtParserFn);
63 m.insert("error-app-tag", ErrorAppTagStmt::parse as StmtParserFn);
64 m.insert("min-elements", MinElementsStmt::parse as StmtParserFn);
65 m.insert("max-elements", MaxElementsStmt::parse as StmtParserFn);
66 m.insert("value", ValueStmt::parse as StmtParserFn);
67 m.insert("grouping", GroupingStmt::parse as StmtParserFn);
68 m.insert("container", ContainerStmt::parse as StmtParserFn);
69 m.insert("leaf", LeafStmt::parse as StmtParserFn);
70 m.insert("leaf-list", LeafListStmt::parse as StmtParserFn);
71 m.insert("list", ListStmt::parse as StmtParserFn);
72 m.insert("key", KeyStmt::parse as StmtParserFn);
73 m.insert("unique", UniqueStmt::parse as StmtParserFn);
74 m.insert("choice", ChoiceStmt::parse as StmtParserFn);
75 m.insert("case", CaseStmt::parse as StmtParserFn);
76 m.insert("anydata", AnydataStmt::parse as StmtParserFn);
77 m.insert("anyxml", AnyxmlStmt::parse as StmtParserFn);
78 m.insert("uses", UsesStmt::parse as StmtParserFn);
79 m.insert("refine", RefineStmt::parse as StmtParserFn);
80 m.insert("augment", AugmentStmt::parse as StmtParserFn);
81 m.insert("when", WhenStmt::parse as StmtParserFn);
82 m.insert("rpc", RpcStmt::parse as StmtParserFn);
83 m.insert("action", ActionStmt::parse as StmtParserFn);
84 m.insert("input", InputStmt::parse as StmtParserFn);
85 m.insert("output", OutputStmt::parse as StmtParserFn);
86 m.insert("notification", NotificationStmt::parse as StmtParserFn);
87 m.insert("deviation", DeviationStmt::parse as StmtParserFn);
88 m.insert("deviate", DeviateStmt::parse as StmtParserFn);
89 m
90 };
91}
92
93pub type Keyword = &'static str;
95
96pub type StmtCollection = HashMap<String, Vec<YangStmt>>;
98
99type StmtParserFn = fn(&mut Parser) -> Result<YangStmt, YangError>;
101
102#[derive(Clone, PartialEq)]
104pub enum YangStmt {
105 ModuleStmt(ModuleStmt),
106 SubmoduleStmt(SubmoduleStmt),
107 YangVersionStmt(YangVersionStmt),
108 ImportStmt(ImportStmt),
109 IncludeStmt(IncludeStmt),
110 NamespaceStmt(NamespaceStmt),
111 PrefixStmt(PrefixStmt),
112 BelongsToStmt(BelongsToStmt),
113 OrganizationStmt(OrganizationStmt),
114 ContactStmt(ContactStmt),
115 DescriptionStmt(DescriptionStmt),
116 ReferenceStmt(ReferenceStmt),
117 UnitsStmt(UnitsStmt),
118 RevisionStmt(RevisionStmt),
119 RevisionDateStmt(RevisionDateStmt),
120 ExtensionStmt(ExtensionStmt),
121 ArgumentStmt(ArgumentStmt),
122 YinElementStmt(YinElementStmt),
123 IdentityStmt(IdentityStmt),
124 BaseStmt(BaseStmt),
125 FeatureStmt(FeatureStmt),
126 IfFeatureStmt(IfFeatureStmt),
127 TypedefStmt(TypedefStmt),
128 TypeStmt(TypeStmt),
129 RangeStmt(RangeStmt),
130 FractionDigitsStmt(FractionDigitsStmt),
131 LengthStmt(LengthStmt),
132 PatternStmt(PatternStmt),
133 ModifierStmt(ModifierStmt),
134 DefaultStmt(DefaultStmt),
135 EnumStmt(EnumStmt),
136 PathStmt(PathStmt),
137 RequireInstanceStmt(RequireInstanceStmt),
138 BitStmt(BitStmt),
139 PositionStmt(PositionStmt),
140 StatusStmt(StatusStmt),
141 ConfigStmt(ConfigStmt),
142 MandatoryStmt(MandatoryStmt),
143 PresenceStmt(PresenceStmt),
144 OrderedByStmt(OrderedByStmt),
145 MustStmt(MustStmt),
146 ErrorMessageStmt(ErrorMessageStmt),
147 ErrorAppTagStmt(ErrorAppTagStmt),
148 MinElementsStmt(MinElementsStmt),
149 MaxElementsStmt(MaxElementsStmt),
150 ValueStmt(ValueStmt),
151 GroupingStmt(GroupingStmt),
152 ContainerStmt(ContainerStmt),
153 LeafStmt(LeafStmt),
154 LeafListStmt(LeafListStmt),
155 ListStmt(ListStmt),
156 KeyStmt(KeyStmt),
157 UniqueStmt(UniqueStmt),
158 ChoiceStmt(ChoiceStmt),
159 CaseStmt(CaseStmt),
160 AnydataStmt(AnydataStmt),
161 AnyxmlStmt(AnyxmlStmt),
162 UsesStmt(UsesStmt),
163 RefineStmt(RefineStmt),
164 AugmentStmt(AugmentStmt),
165 WhenStmt(WhenStmt),
166 RpcStmt(RpcStmt),
167 ActionStmt(ActionStmt),
168 InputStmt(InputStmt),
169 OutputStmt(OutputStmt),
170 NotificationStmt(NotificationStmt),
171 DeviationStmt(DeviationStmt),
172 DeviateStmt(DeviateStmt),
173 UnknownStmt(UnknownStmt),
174}
175
176impl fmt::Debug for YangStmt {
177 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
178 match &*self {
179 YangStmt::ModuleStmt(stmt) => write!(f, "{:?}", stmt),
180 YangStmt::SubmoduleStmt(stmt) => write!(f, "{:?}", stmt),
181 YangStmt::YangVersionStmt(stmt) => write!(f, "{:?}", stmt),
182 YangStmt::ImportStmt(stmt) => write!(f, "{:?}", stmt),
183 YangStmt::IncludeStmt(stmt) => write!(f, "{:?}", stmt),
184 YangStmt::NamespaceStmt(stmt) => write!(f, "{:?}", stmt),
185 YangStmt::PrefixStmt(stmt) => write!(f, "{:?}", stmt),
186 YangStmt::BelongsToStmt(stmt) => write!(f, "{:?}", stmt),
187 YangStmt::OrganizationStmt(stmt) => write!(f, "{:?}", stmt),
188 YangStmt::ContactStmt(stmt) => write!(f, "{:?}", stmt),
189 YangStmt::DescriptionStmt(stmt) => write!(f, "{:?}", stmt),
190 YangStmt::ReferenceStmt(stmt) => write!(f, "{:?}", stmt),
191 YangStmt::UnitsStmt(stmt) => write!(f, "{:?}", stmt),
192 YangStmt::RevisionStmt(stmt) => write!(f, "{:?}", stmt),
193 YangStmt::RevisionDateStmt(stmt) => write!(f, "{:?}", stmt),
194 YangStmt::ExtensionStmt(stmt) => write!(f, "{:?}", stmt),
195 YangStmt::ArgumentStmt(stmt) => write!(f, "{:?}", stmt),
196 YangStmt::YinElementStmt(stmt) => write!(f, "{:?}", stmt),
197 YangStmt::IdentityStmt(stmt) => write!(f, "{:?}", stmt),
198 YangStmt::BaseStmt(stmt) => write!(f, "{:?}", stmt),
199 YangStmt::FeatureStmt(stmt) => write!(f, "{:?}", stmt),
200 YangStmt::IfFeatureStmt(stmt) => write!(f, "{:?}", stmt),
201 YangStmt::TypedefStmt(stmt) => write!(f, "{:?}", stmt),
202 YangStmt::TypeStmt(stmt) => write!(f, "{:?}", stmt),
203 YangStmt::RangeStmt(stmt) => write!(f, "{:?}", stmt),
204 YangStmt::FractionDigitsStmt(stmt) => write!(f, "{:?}", stmt),
205 YangStmt::LengthStmt(stmt) => write!(f, "{:?}", stmt),
206 YangStmt::PatternStmt(stmt) => write!(f, "{:?}", stmt),
207 YangStmt::ModifierStmt(stmt) => write!(f, "{:?}", stmt),
208 YangStmt::DefaultStmt(stmt) => write!(f, "{:?}", stmt),
209 YangStmt::EnumStmt(stmt) => write!(f, "{:?}", stmt),
210 YangStmt::PathStmt(stmt) => write!(f, "{:?}", stmt),
211 YangStmt::RequireInstanceStmt(stmt) => write!(f, "{:?}", stmt),
212 YangStmt::BitStmt(stmt) => write!(f, "{:?}", stmt),
213 YangStmt::PositionStmt(stmt) => write!(f, "{:?}", stmt),
214 YangStmt::StatusStmt(stmt) => write!(f, "{:?}", stmt),
215 YangStmt::ConfigStmt(stmt) => write!(f, "{:?}", stmt),
216 YangStmt::MandatoryStmt(stmt) => write!(f, "{:?}", stmt),
217 YangStmt::PresenceStmt(stmt) => write!(f, "{:?}", stmt),
218 YangStmt::OrderedByStmt(stmt) => write!(f, "{:?}", stmt),
219 YangStmt::MustStmt(stmt) => write!(f, "{:?}", stmt),
220 YangStmt::ErrorMessageStmt(stmt) => write!(f, "{:?}", stmt),
221 YangStmt::ErrorAppTagStmt(stmt) => write!(f, "{:?}", stmt),
222 YangStmt::MinElementsStmt(stmt) => write!(f, "{:?}", stmt),
223 YangStmt::MaxElementsStmt(stmt) => write!(f, "{:?}", stmt),
224 YangStmt::ValueStmt(stmt) => write!(f, "{:?}", stmt),
225 YangStmt::GroupingStmt(stmt) => write!(f, "{:?}", stmt),
226 YangStmt::ContainerStmt(stmt) => write!(f, "{:?}", stmt),
227 YangStmt::LeafStmt(stmt) => write!(f, "{:?}", stmt),
228 YangStmt::LeafListStmt(stmt) => write!(f, "{:?}", stmt),
229 YangStmt::ListStmt(stmt) => write!(f, "{:?}", stmt),
230 YangStmt::KeyStmt(stmt) => write!(f, "{:?}", stmt),
231 YangStmt::UniqueStmt(stmt) => write!(f, "{:?}", stmt),
232 YangStmt::ChoiceStmt(stmt) => write!(f, "{:?}", stmt),
233 YangStmt::CaseStmt(stmt) => write!(f, "{:?}", stmt),
234 YangStmt::AnydataStmt(stmt) => write!(f, "{:?}", stmt),
235 YangStmt::AnyxmlStmt(stmt) => write!(f, "{:?}", stmt),
236 YangStmt::UsesStmt(stmt) => write!(f, "{:?}", stmt),
237 YangStmt::RefineStmt(stmt) => write!(f, "{:?}", stmt),
238 YangStmt::AugmentStmt(stmt) => write!(f, "{:?}", stmt),
239 YangStmt::WhenStmt(stmt) => write!(f, "{:?}", stmt),
240 YangStmt::RpcStmt(stmt) => write!(f, "{:?}", stmt),
241 YangStmt::ActionStmt(stmt) => write!(f, "{:?}", stmt),
242 YangStmt::InputStmt(stmt) => write!(f, "{:?}", stmt),
243 YangStmt::OutputStmt(stmt) => write!(f, "{:?}", stmt),
244 YangStmt::NotificationStmt(stmt) => write!(f, "{:?}", stmt),
245 YangStmt::DeviationStmt(stmt) => write!(f, "{:?}", stmt),
246 YangStmt::DeviateStmt(stmt) => write!(f, "{:?}", stmt),
247 YangStmt::UnknownStmt(stmt) => write!(f, "{:?}", stmt),
248 }
249 }
250}
251
252pub fn is_node_identifier(s: &str) -> bool {
254 let parts: Vec<_> = s.split(":").collect();
255
256 if parts.len() == 1 {
257 is_identifier(parts[0])
258 } else if parts.len() == 2 {
259 is_identifier(parts[0]) && is_identifier(parts[1])
260 } else {
261 false
262 }
263}
264
265pub fn is_current_function_invocation(s: &str) -> bool {
266 let s = s.trim();
267
268 if !s.starts_with("current") {
269 false
270 } else {
271 let s = &s[7..].trim_start();
272
273 if !s.starts_with("(") {
274 false
275 } else {
276 let s = &s[1..].trim();
277
278 if s != &")" {
279 false
280 } else {
281 true
282 }
283 }
284 }
285}
286
287pub fn is_identifier(s: &str) -> bool {
288 if !s.starts_with(|c: char| c.is_alphabetic() || c == '_') {
289 false
290 } else if s.len() > 1 {
291 if let Some(_) = &s[1..].find(|c: char| {
292 !c.is_alphabetic() && !c.is_ascii_digit() && c != '_' && c != '-' && c != '.'
293 }) {
294 false
295 } else {
296 true
297 }
298 } else {
299 true
300 }
301}
302
303pub fn is_integer_value(s: &str) -> bool {
304 if s.starts_with("-") {
305 is_non_negative_integer_value(&s[1..])
306 } else {
307 is_non_negative_integer_value(s)
308 }
309}
310
311pub fn is_non_negative_integer_value(s: &str) -> bool {
312 s == "0" || is_positive_integer_value(s)
313}
314
315pub fn is_positive_integer_value(s: &str) -> bool {
316 let mut chars = s.chars();
317 let c = chars.next().unwrap();
318
319 if c != '0' && c.is_ascii_digit() {
320 chars.all(|c: char| c.is_ascii_digit())
321 } else {
322 false
323 }
324}
325
326fn is_zero_integer_value(s: &str) -> bool {
327 s.chars().all(|c: char| c.is_ascii_digit())
328}
329
330pub fn is_decimal_value(s: &str) -> bool {
331 if let Some(p) = s.find('.') {
332 let is = &s[..p];
333 let fs = &s[p + 1..];
334
335 if is_integer_value(is) && fs.len() > 0 {
336 is_zero_integer_value(fs)
337 } else {
338 false
339 }
340 } else {
341 false
342 }
343}
344
345#[cfg(test)]
346mod tests {
347 use super::*;
348
349 #[test]
350 pub fn test_current_function_invocation() {
351 let s = "current()";
352 assert_eq!(is_current_function_invocation(&s), true);
353
354 let s = " current () ";
355 assert_eq!(is_current_function_invocation(&s), true);
356
357 let s = "current ( )";
358 assert_eq!(is_current_function_invocation(&s), true);
359
360 let s = "current ( ) ";
361 assert_eq!(is_current_function_invocation(&s), true);
362
363 let s = "current ( ) ";
364 assert_eq!(is_current_function_invocation(&s), true);
365
366 let s = "current ( 0 ) ";
367 assert_eq!(is_current_function_invocation(&s), false);
368 }
369
370 #[test]
371 pub fn test_identifier() {
372 let s = "identifier";
373 assert_eq!(is_identifier(&s), true);
374
375 let s = "_0123456789-abcdefghijklmnokprstuvwxyz_";
376 assert_eq!(is_identifier(&s), true);
377
378 let s = "_ABCDEFGHIJKLMNOKPRSTUVWXYZ-0123456789_";
379 assert_eq!(is_identifier(&s), true);
380
381 let s = "1a";
382 assert_eq!(is_identifier(&s), false);
383
384 let s = "_";
385 assert_eq!(is_identifier(&s), true);
386
387 let s = "_3.14159265";
388 assert_eq!(is_identifier(&s), true);
389
390 let s = "_127.0.0.1";
391 assert_eq!(is_identifier(&s), true);
392
393 let s = "_ff02::1";
394 assert_eq!(is_identifier(&s), false);
395 }
396
397 #[test]
398 pub fn test_integer_value() {
399 let s = "0123456789";
400 assert_eq!(is_integer_value(&s), false);
401
402 let s = "0";
403 assert_eq!(is_integer_value(&s), true);
404
405 let s = "1234567890";
406 assert_eq!(is_integer_value(&s), true);
407
408 let s = "abc";
409 assert_eq!(is_integer_value(&s), false);
410
411 let s = "-1";
412 assert_eq!(is_integer_value(&s), true);
413
414 let s = "3.14159265";
415 assert_eq!(is_integer_value(&s), false);
416 }
417
418 #[test]
419 pub fn test_non_negative_integer_value() {
420 let s = "0123456789";
421 assert_eq!(is_non_negative_integer_value(&s), false);
422
423 let s = "0";
424 assert_eq!(is_non_negative_integer_value(&s), true);
425
426 let s = "1234567890";
427 assert_eq!(is_non_negative_integer_value(&s), true);
428
429 let s = "abc";
430 assert_eq!(is_non_negative_integer_value(&s), false);
431
432 let s = "-1";
433 assert_eq!(is_non_negative_integer_value(&s), false);
434
435 let s = "3.14159265";
436 assert_eq!(is_non_negative_integer_value(&s), false);
437 }
438
439 #[test]
440 pub fn test_positive_integer_value() {
441 let s = "0123456789";
442 assert_eq!(is_positive_integer_value(&s), false);
443
444 let s = "0";
445 assert_eq!(is_positive_integer_value(&s), false);
446
447 let s = "1234567890";
448 assert_eq!(is_positive_integer_value(&s), true);
449
450 let s = "abc";
451 assert_eq!(is_positive_integer_value(&s), false);
452
453 let s = "-1";
454 assert_eq!(is_positive_integer_value(&s), false);
455
456 let s = "3.14159265";
457 assert_eq!(is_positive_integer_value(&s), false);
458 }
459
460 #[test]
461 pub fn test_zero_integer_value() {
462 let s = "0123456789";
463 assert_eq!(is_zero_integer_value(&s), true);
464
465 let s = "0";
466 assert_eq!(is_zero_integer_value(&s), true);
467
468 let s = "1234567890";
469 assert_eq!(is_zero_integer_value(&s), true);
470
471 let s = "abc";
472 assert_eq!(is_zero_integer_value(&s), false);
473
474 let s = "-1";
475 assert_eq!(is_zero_integer_value(&s), false);
476
477 let s = "3.14159265";
478 assert_eq!(is_zero_integer_value(&s), false);
479 }
480
481 #[test]
482 pub fn test_decimal_value() {
483 let s = "0123456789";
484 assert_eq!(is_decimal_value(&s), false);
485
486 let s = "0";
487 assert_eq!(is_decimal_value(&s), false);
488
489 let s = "1234567890";
490 assert_eq!(is_decimal_value(&s), false);
491
492 let s = "abc";
493 assert_eq!(is_decimal_value(&s), false);
494
495 let s = "-1.0";
496 assert_eq!(is_decimal_value(&s), true);
497
498 let s = "3.14159265";
499 assert_eq!(is_decimal_value(&s), true);
500 }
501}