1use std::fmt;
7use std::iter::Iterator;
8use std::str::FromStr;
9use std::string::ToString;
10use url::Url;
11
12use derive_getters::Getters;
13
14use super::core::*;
15use super::error::*;
16use super::parser::*;
17
18pub type Prefix = Identifier;
20
21fn parse_string(parser: &mut Parser) -> Result<String, YangError> {
51 let token = parser.get_token()?;
52 match token {
53 Token::Identifier(s) | Token::QuotedString(s) => Ok(s),
55 Token::EndOfInput => Err(YangError::UnexpectedEof),
57 _ => Err(YangError::UnexpectedToken(token.to_string())),
59 }
60}
61
62pub trait StmtArg {
66 fn parse_arg(parser: &mut Parser) -> Result<Self, YangError>
68 where
69 Self: Sized;
70}
71
72#[derive(Debug, Clone, PartialEq)]
76pub struct NoArg;
77
78impl StmtArg for NoArg {
79 fn parse_arg(_parser: &mut Parser) -> Result<Self, YangError> {
80 Ok(NoArg)
81 }
82}
83
84#[derive(Debug, Clone, PartialEq, Getters)]
88pub struct Identifier {
89 str: String,
90}
91
92impl fmt::Display for Identifier {
93 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
94 write!(f, "{}", self.str)
95 }
96}
97
98impl FromStr for Identifier {
99 type Err = ArgError;
100
101 fn from_str(s: &str) -> Result<Self, Self::Err> {
102 if is_identifier(s) {
103 Ok(Identifier { str: s.to_string() })
104 } else {
105 Err(ArgError::new("identifier"))
106 }
107 }
108}
109
110impl StmtArg for Identifier {
111 fn parse_arg(parser: &mut Parser) -> Result<Self, YangError> {
112 let str = parse_string(parser)?;
113
114 match Identifier::from_str(&str) {
115 Ok(arg) => Ok(arg),
116 Err(e) => Err(YangError::ArgumentParseError(e.str)),
117 }
118 }
119}
120
121#[derive(Clone, PartialEq, Getters)]
125pub struct IdentifierRef {
126 prefix: Option<Prefix>,
127 identifier: Identifier,
128}
129
130impl fmt::Debug for IdentifierRef {
131 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
132 match &self.prefix {
133 Some(prefix) => write!(f, "{}:{}", prefix, self.identifier),
134 None => write!(f, "{}", self.identifier),
135 }
136 }
137}
138
139impl ToString for IdentifierRef {
140 fn to_string(&self) -> String {
141 match &self.prefix {
142 Some(prefix) => format!("{}:{}", prefix, self.identifier),
143 None => format!("{}", self.identifier),
144 }
145 }
146}
147
148impl FromStr for IdentifierRef {
149 type Err = ArgError;
150
151 fn from_str(str: &str) -> Result<Self, Self::Err> {
152 match str.find(":") {
153 Some(p) => {
154 let prefix = Identifier::from_str(&str[..p])?;
155 let identifier = Identifier::from_str(&str[p + 1..])?;
156
157 Ok(IdentifierRef {
158 prefix: Some(prefix),
159 identifier,
160 })
161 }
162 None => {
163 let identifier = Identifier::from_str(&str)?;
164 Ok(IdentifierRef {
165 prefix: None,
166 identifier,
167 })
168 }
169 }
170 }
171}
172
173impl StmtArg for IdentifierRef {
174 fn parse_arg(parser: &mut Parser) -> Result<Self, YangError> {
175 let str = parse_string(parser)?;
176 IdentifierRef::from_str(&str).map_err(|e| YangError::ArgumentParseError(e.str))
177 }
178}
179
180#[derive(Clone, PartialEq, Getters)]
184pub struct NodeIdentifier {
185 prefix: Option<Prefix>,
186 identifier: Identifier,
187}
188
189impl fmt::Debug for NodeIdentifier {
190 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
191 match &self.prefix {
192 Some(prefix) => write!(f, "{}:{}", prefix, self.identifier),
193 None => write!(f, "{}", self.identifier),
194 }
195 }
196}
197
198impl FromStr for NodeIdentifier {
199 type Err = ArgError;
200
201 fn from_str(s: &str) -> Result<Self, Self::Err> {
202 match s.find(":") {
203 Some(p) => {
204 let prefix = Identifier::from_str(&s[..p])?;
205 let identifier = Identifier::from_str(&s[p + 1..])?;
206
207 Ok(NodeIdentifier {
208 prefix: Some(prefix),
209 identifier,
210 })
211 }
212 None => {
213 let identifier = Identifier::from_str(&s)?;
214 Ok(NodeIdentifier {
215 prefix: None,
216 identifier,
217 })
218 }
219 }
220 }
221}
222
223impl ToString for NodeIdentifier {
224 fn to_string(&self) -> String {
225 match &self.prefix {
226 Some(prefix) => format!("{}:{}", prefix, self.identifier),
227 None => format!("{}", self.identifier),
228 }
229 }
230}
231
232impl StmtArg for NodeIdentifier {
233 fn parse_arg(parser: &mut Parser) -> Result<Self, YangError> {
234 let str = parse_string(parser)?;
235 NodeIdentifier::from_str(&str).map_err(|e| YangError::ArgumentParseError(e.str))
236 }
237}
238
239#[derive(Clone, PartialEq, Getters)]
243pub struct UnknownStmtKeyword {
244 prefix: Prefix,
245 identifier: Identifier,
246}
247
248impl fmt::Debug for UnknownStmtKeyword {
249 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
250 write!(f, "{}:{}", self.prefix, self.identifier)
251 }
252}
253
254impl ToString for UnknownStmtKeyword {
255 fn to_string(&self) -> String {
256 format!("{}:{}", self.prefix, self.identifier)
257 }
258}
259
260impl FromStr for UnknownStmtKeyword {
261 type Err = ArgError;
262
263 fn from_str(str: &str) -> Result<Self, Self::Err> {
264 match str.find(":") {
265 Some(p) => {
266 let prefix = Identifier::from_str(&str[..p])?;
267 let identifier = Identifier::from_str(&str[p + 1..])?;
268
269 Ok(UnknownStmtKeyword { prefix, identifier })
270 }
271 None => Err(ArgError::new("unknown-stmt keyword")),
272 }
273 }
274}
275
276impl StmtArg for String {
278 fn parse_arg(parser: &mut Parser) -> Result<Self, YangError> {
279 Ok(parse_string(parser)?)
280 }
281}
282
283impl StmtArg for Url {
285 fn parse_arg(parser: &mut Parser) -> Result<Self, YangError> {
286 let s = parse_string(parser)?;
287
288 match Url::parse(&s) {
289 Ok(url) => Ok(url),
290 Err(_) => Err(YangError::ArgumentParseError("url")),
291 }
292 }
293}
294
295#[derive(Debug, Clone, PartialEq, Getters)]
299pub struct YangVersionArg {
300 str: String,
301}
302
303impl StmtArg for YangVersionArg {
304 fn parse_arg(parser: &mut Parser) -> Result<Self, YangError> {
305 let str = parse_string(parser)?;
306
307 match parser.config().yang_version() {
310 Some(yang_version) => {
311 if str == yang_version {
312 Ok(YangVersionArg { str })
313 } else {
314 Err(YangError::ArgumentParseError("yang-version"))
315 }
316 }
317 None => Ok(YangVersionArg { str }),
318 }
319 }
320}
321
322#[derive(Debug, Clone, PartialEq, Getters)]
326pub struct DateArg {
327 str: String,
328}
329
330impl ToString for DateArg {
331 fn to_string(&self) -> String {
332 self.str.clone()
333 }
334}
335
336impl FromStr for DateArg {
337 type Err = ArgError;
338
339 fn from_str(s: &str) -> Result<Self, Self::Err> {
340 Ok(DateArg { str: s.to_string() })
341 }
342}
343
344impl StmtArg for DateArg {
345 fn parse_arg(parser: &mut Parser) -> Result<Self, YangError> {
346 let str = parse_string(parser)?;
347
348 if str.chars().count() == 10 {
349 if let Some(_) = &str[0..4].find(|c: char| !c.is_ascii_digit()) {
350 Err(YangError::ArgumentParseError("date-arg"))
351 } else if str.chars().nth(4).unwrap() != '-' {
352 Err(YangError::ArgumentParseError("date-arg"))
353 } else if let Some(_) = &str[5..7].find(|c: char| !c.is_ascii_digit()) {
354 Err(YangError::ArgumentParseError("date-arg"))
355 } else if str.chars().nth(7).unwrap() != '-' {
356 Err(YangError::ArgumentParseError("date-arg"))
357 } else if let Some(_) = &str[8..10].find(|c: char| !c.is_ascii_digit()) {
358 Err(YangError::ArgumentParseError("date-arg"))
359 } else {
360 Ok(DateArg { str })
361 }
362 } else {
363 Err(YangError::ArgumentParseError("date-arg"))
364 }
365 }
366}
367
368#[derive(Debug, Clone, PartialEq, Getters)]
372pub struct YinElementArg {
373 arg: bool,
374}
375
376impl FromStr for YinElementArg {
377 type Err = ArgError;
378
379 fn from_str(s: &str) -> Result<Self, Self::Err> {
380 if s == "true" {
381 Ok(YinElementArg { arg: true })
382 } else if s == "false" {
383 Ok(YinElementArg { arg: false })
384 } else {
385 Err(ArgError::new("yin-element-arg"))
386 }
387 }
388}
389
390impl StmtArg for YinElementArg {
391 fn parse_arg(parser: &mut Parser) -> Result<Self, YangError> {
392 let str = parse_string(parser)?;
393
394 YinElementArg::from_str(&str).map_err(|_| YangError::ArgumentParseError("yin-element-arg"))
395 }
396}
397
398#[derive(Debug, Clone, PartialEq, Getters)]
402pub struct FractionDigitsArg {
403 digits: u8,
404}
405
406impl ToString for FractionDigitsArg {
407 fn to_string(&self) -> String {
408 format!("{}", self.digits())
409 }
410}
411
412impl StmtArg for FractionDigitsArg {
413 fn parse_arg(parser: &mut Parser) -> Result<Self, YangError> {
414 let str = parse_string(parser)?;
415 match str.parse::<u8>() {
416 Ok(num) if num >= 1 && num <= 18 => Ok(FractionDigitsArg { digits: num }),
417 _ => Err(YangError::ArgumentParseError("fraction-digits-arg")),
418 }
419 }
420}
421
422#[derive(Debug, Copy, Clone, PartialEq)]
423pub enum Status {
424 Current,
425 Obsolete,
426 Deprecated,
427}
428
429#[derive(Debug, Clone, PartialEq, Getters)]
433pub struct StatusArg {
434 arg: Status,
435}
436
437impl StmtArg for StatusArg {
438 fn parse_arg(parser: &mut Parser) -> Result<Self, YangError> {
439 let str = parse_string(parser)?;
440 if str == "current" {
441 Ok(StatusArg {
442 arg: Status::Current,
443 })
444 } else if str == "obsolete" {
445 Ok(StatusArg {
446 arg: Status::Obsolete,
447 })
448 } else if str == "deprecated" {
449 Ok(StatusArg {
450 arg: Status::Deprecated,
451 })
452 } else {
453 Err(YangError::ArgumentParseError("status-arg"))
454 }
455 }
456}
457
458#[derive(Debug, Clone, PartialEq, Getters)]
462pub struct ConfigArg {
463 arg: bool,
464}
465
466impl StmtArg for ConfigArg {
467 fn parse_arg(parser: &mut Parser) -> Result<Self, YangError> {
468 let str = parse_string(parser)?;
469 if str == "true" {
470 Ok(ConfigArg { arg: true })
471 } else if str == "false" {
472 Ok(ConfigArg { arg: false })
473 } else {
474 Err(YangError::ArgumentParseError("config-arg"))
475 }
476 }
477}
478
479#[derive(Debug, Clone, PartialEq, Getters)]
483pub struct MandatoryArg {
484 arg: bool,
485}
486
487impl StmtArg for MandatoryArg {
488 fn parse_arg(parser: &mut Parser) -> Result<Self, YangError> {
489 let str = parse_string(parser)?;
490 if str == "true" {
491 Ok(MandatoryArg { arg: true })
492 } else if str == "false" {
493 Ok(MandatoryArg { arg: false })
494 } else {
495 Err(YangError::ArgumentParseError("mandatory-arg"))
496 }
497 }
498}
499
500#[derive(Debug, Copy, Clone, PartialEq)]
501pub enum OrderedBy {
502 User,
503 System,
504}
505
506#[derive(Debug, Clone, PartialEq, Getters)]
510pub struct OrderedByArg {
511 arg: OrderedBy,
512}
513
514impl StmtArg for OrderedByArg {
515 fn parse_arg(parser: &mut Parser) -> Result<Self, YangError> {
516 let str = parse_string(parser)?;
517 if str == "user" {
518 Ok(OrderedByArg {
519 arg: OrderedBy::User,
520 })
521 } else if str == "system" {
522 Ok(OrderedByArg {
523 arg: OrderedBy::System,
524 })
525 } else {
526 Err(YangError::ArgumentParseError("ordered-by-arg"))
527 }
528 }
529}
530
531#[derive(Debug, Clone, PartialEq, Getters)]
535pub struct MinValueArg {
536 val: u64,
537}
538
539impl StmtArg for MinValueArg {
540 fn parse_arg(parser: &mut Parser) -> Result<Self, YangError> {
541 let str = parse_string(parser)?;
542 if is_non_negative_integer_value(&str) {
543 match str.parse::<u64>() {
544 Ok(num) => Ok(MinValueArg { val: num }),
545 Err(_) => Err(YangError::ArgumentParseError("min-value-arg")),
546 }
547 } else {
548 Err(YangError::ArgumentParseError("min-value-arg"))
549 }
550 }
551}
552
553#[derive(Clone, PartialEq)]
554pub enum MaxValue {
555 Unbounded,
556 Value(u64),
557}
558
559impl fmt::Debug for MaxValue {
560 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
561 match &self {
562 MaxValue::Unbounded => write!(f, "unbounded"),
563 MaxValue::Value(num) => write!(f, "{}", num),
564 }
565 }
566}
567
568#[derive(Debug, Clone, PartialEq, Getters)]
572pub struct MaxValueArg {
573 val: MaxValue,
574}
575
576impl StmtArg for MaxValueArg {
577 fn parse_arg(parser: &mut Parser) -> Result<Self, YangError> {
578 let str = parse_string(parser)?;
579
580 if str == "unbounded" {
581 Ok(MaxValueArg {
582 val: MaxValue::Unbounded,
583 })
584 } else if is_positive_integer_value(&str) {
585 match str.parse::<u64>() {
586 Ok(num) => Ok(MaxValueArg {
587 val: MaxValue::Value(num),
588 }),
589 Err(_) => Err(YangError::ArgumentParseError("max-value-arg")),
590 }
591 } else {
592 Err(YangError::ArgumentParseError("max-value-arg"))
593 }
594 }
595}
596
597#[derive(Debug, Clone, PartialEq, Getters)]
601pub struct IntegerValue {
602 val: i64,
603}
604
605impl StmtArg for IntegerValue {
606 fn parse_arg(parser: &mut Parser) -> Result<Self, YangError> {
607 let str = parse_string(parser)?;
608 if is_integer_value(&str) {
609 match str.parse::<i64>() {
610 Ok(num) => Ok(IntegerValue { val: num }),
611 Err(_) => Err(YangError::ArgumentParseError("integer-value")),
612 }
613 } else {
614 Err(YangError::ArgumentParseError("integer-value"))
615 }
616 }
617}
618
619#[derive(Debug, Copy, Clone, PartialEq)]
620pub enum RangeBoundary {
621 Min,
622 Max,
623 Integer(i64),
624 Decimal(f64),
625}
626
627impl FromStr for RangeBoundary {
628 type Err = ArgError;
629
630 fn from_str(s: &str) -> Result<Self, Self::Err> {
631 let rb = s.trim();
632
633 if rb == "min" {
634 Ok(RangeBoundary::Min)
635 } else if rb == "max" {
636 Ok(RangeBoundary::Max)
637 } else if is_decimal_value(rb) {
638 match rb.parse::<f64>() {
639 Ok(num) => Ok(RangeBoundary::Decimal(num)),
640 Err(_) => Err(ArgError::new("range-arg")),
641 }
642 } else if is_integer_value(rb) {
643 match rb.parse::<i64>() {
644 Ok(num) => Ok(RangeBoundary::Integer(num)),
645 Err(_) => Err(ArgError::new("range-arg")),
646 }
647 } else {
648 Err(ArgError::new("range-arg"))
649 }
650 }
651}
652
653pub type RangePart = (RangeBoundary, Option<RangeBoundary>);
654
655#[derive(Debug, Clone, PartialEq, Getters)]
659pub struct RangeArg {
660 parts: Vec<RangePart>,
661}
662
663impl StmtArg for RangeArg {
664 fn parse_arg(parser: &mut Parser) -> Result<Self, YangError> {
665 let str = parse_string(parser)?;
666 let parts: Vec<_> = str.split('|').collect();
667 let mut v = Vec::new();
668
669 for p in parts {
670 let lower;
671 let upper;
672
673 let bounds: Vec<_> = p.split("..").collect();
674 if bounds.len() == 1 {
675 if bounds[0] == "" {
676 return Err(YangError::ArgumentParseError("range-arg"));
677 }
678
679 lower = RangeBoundary::from_str(bounds[0])
680 .map_err(|e| YangError::ArgumentParseError(e.str))?;
681 upper = None;
682 } else if bounds.len() == 2 {
683 if bounds[0] == "" || bounds[1] == "" {
684 return Err(YangError::ArgumentParseError("range-arg"));
685 }
686 lower = RangeBoundary::from_str(bounds[0])
687 .map_err(|e| YangError::ArgumentParseError(e.str))?;
688 upper = Some(
689 RangeBoundary::from_str(bounds[1])
690 .map_err(|e| YangError::ArgumentParseError(e.str))?,
691 );
692 } else {
693 return Err(YangError::ArgumentParseError("range-arg"));
694 }
695
696 v.push((lower, upper));
697 }
698
699 Ok(RangeArg { parts: v })
700 }
701}
702
703#[derive(Debug, Copy, Clone, PartialEq)]
704pub enum LengthBoundary {
705 Min,
706 Max,
707 Integer(u64),
708}
709
710impl FromStr for LengthBoundary {
711 type Err = ArgError;
712
713 fn from_str(s: &str) -> Result<Self, Self::Err> {
714 let lb = s.trim();
715
716 if lb == "min" {
717 Ok(LengthBoundary::Min)
718 } else if lb == "max" {
719 Ok(LengthBoundary::Max)
720 } else if is_integer_value(lb) {
721 match lb.parse::<u64>() {
722 Ok(num) => Ok(LengthBoundary::Integer(num)),
723 Err(_) => Err(ArgError::new("length-arg")),
724 }
725 } else {
726 Err(ArgError::new("length-arg"))
727 }
728 }
729}
730
731pub type LengthPart = (LengthBoundary, Option<LengthBoundary>);
732
733#[derive(Debug, Clone, PartialEq, Getters)]
737pub struct LengthArg {
738 parts: Vec<LengthPart>,
739}
740
741impl StmtArg for LengthArg {
742 fn parse_arg(parser: &mut Parser) -> Result<Self, YangError> {
743 let str = parse_string(parser)?;
744 let parts: Vec<_> = str.split('|').collect();
745 let mut v = Vec::new();
746
747 for p in parts {
748 let lower;
749 let upper;
750
751 let bounds: Vec<_> = p.split("..").collect();
752 if bounds.len() == 1 {
753 if bounds[0] == "" {
754 return Err(YangError::ArgumentParseError("length-arg"));
755 }
756
757 lower = LengthBoundary::from_str(bounds[0])
758 .map_err(|e| YangError::ArgumentParseError(e.str))?;
759 upper = None;
760 } else if bounds.len() == 2 {
761 if bounds[0] == "" || bounds[1] == "" {
762 return Err(YangError::ArgumentParseError("length-arg"));
763 }
764 lower = LengthBoundary::from_str(bounds[0])
765 .map_err(|e| YangError::ArgumentParseError(e.str))?;
766 upper = Some(
767 LengthBoundary::from_str(bounds[1])
768 .map_err(|e| YangError::ArgumentParseError(e.str))?,
769 );
770 } else {
771 return Err(YangError::ArgumentParseError("length-arg"));
772 }
773
774 v.push((lower, upper));
775 }
776
777 Ok(LengthArg { parts: v })
778 }
779}
780
781#[derive(Debug, Clone, PartialEq, Getters)]
785pub struct ModifierArg {}
786
787impl StmtArg for ModifierArg {
788 fn parse_arg(parser: &mut Parser) -> Result<Self, YangError> {
789 let str = parse_string(parser)?;
790 if str == "invert-match" {
791 Ok(ModifierArg {})
792 } else {
793 Err(YangError::ArgumentParseError("modifier-arg"))
794 }
795 }
796}
797
798#[derive(Debug, Clone, PartialEq, Getters)]
802pub struct PositionValueArg {
803 val: u64,
804}
805
806impl StmtArg for PositionValueArg {
807 fn parse_arg(parser: &mut Parser) -> Result<Self, YangError> {
808 let str = parse_string(parser)?;
809 if is_non_negative_integer_value(&str) {
810 match str.parse::<u64>() {
811 Ok(num) => Ok(PositionValueArg { val: num }),
812 Err(_) => Err(YangError::ArgumentParseError("position-value-arg")),
813 }
814 } else {
815 Err(YangError::ArgumentParseError("position-value-arg"))
816 }
817 }
818}
819
820#[derive(Debug, Clone, PartialEq)]
824pub enum PathArg {
825 AbsolutePath(AbsolutePath),
826 RelativePath(RelativePath),
827}
828
829impl StmtArg for PathArg {
830 fn parse_arg(parser: &mut Parser) -> Result<Self, YangError> {
831 let str = parse_string(parser)?;
832
833 if str.starts_with('/') {
834 Ok(PathArg::AbsolutePath(
835 AbsolutePath::from_str(&str).map_err(|e| YangError::ArgumentParseError(e.str))?,
836 ))
837 } else if str.starts_with("..") {
838 Ok(PathArg::RelativePath(
839 RelativePath::from_str(&str).map_err(|e| YangError::ArgumentParseError(e.str))?,
840 ))
841 } else {
842 Err(YangError::ArgumentParseError("path-arg"))
843 }
844 }
845}
846
847#[derive(Debug, Clone, PartialEq, Getters)]
849pub struct AbsolutePath {
850 nodes: Vec<PathNode>,
851}
852
853impl FromStr for AbsolutePath {
854 type Err = ArgError;
855
856 fn from_str(s: &str) -> Result<Self, Self::Err> {
857 let mut s = &s[..];
858 let mut nodes = Vec::new();
859
860 while s.len() > 0 {
861 if !s.starts_with('/') {
862 return Err(ArgError::new("absolute-path"));
863 }
864 s = &s[1..];
865
866 let node_identifier;
867 let mut path_predicate = Vec::new();
868
869 match s.find(|c: char| c == '[' || c == '/') {
870 Some(pos) => {
871 node_identifier = NodeIdentifier::from_str(&s[..pos])?;
872 s = &s[pos..];
873
874 if s.starts_with('[') {
875 while {
877 let pos = match s.find(']') {
878 Some(p) => Ok(p + 1),
879 None => Err(ArgError::new("absolute-path")),
880 }?;
881
882 path_predicate.push(PathPredicate::from_str(&s[..pos])?);
883 s = &s[pos..];
884
885 s.len() > 0 && s.starts_with('[')
886 } {}
887 }
888 }
889 None => {
890 node_identifier = NodeIdentifier::from_str(&s)?;
891 nodes.push(PathNode {
892 node_identifier,
893 path_predicate,
894 });
895 break;
896 }
897 }
898
899 nodes.push(PathNode {
900 node_identifier,
901 path_predicate,
902 });
903 }
904
905 Ok(AbsolutePath { nodes })
906 }
907}
908
909#[derive(Debug, Clone, PartialEq, Getters)]
910pub struct PathNode {
911 node_identifier: NodeIdentifier,
912 path_predicate: Vec<PathPredicate>,
913}
914
915#[derive(Debug, Clone, PartialEq, Getters)]
917pub struct RelativePath {
918 up: u32,
919 descendant_path: DescendantPath,
920}
921
922impl FromStr for RelativePath {
923 type Err = ArgError;
924
925 fn from_str(s: &str) -> Result<Self, Self::Err> {
926 let mut s = &s[..];
927 let mut up = 0;
928
929 if !s.starts_with("../") {
930 return Err(ArgError::new("relative-path"));
931 }
932
933 while {
934 up += 1;
935 s = &s[3..];
936 s.len() > 0 && s.starts_with("../")
937 } {}
938
939 let descendant_path = DescendantPath::from_str(s)?;
940 Ok(RelativePath {
941 up,
942 descendant_path,
943 })
944 }
945}
946
947#[derive(Debug, Clone, PartialEq, Getters)]
949pub struct DescendantPath {
950 node_identifier: NodeIdentifier,
951 path_predicate: Vec<PathPredicate>,
952 absolute_path: Option<AbsolutePath>,
953}
954
955impl FromStr for DescendantPath {
956 type Err = ArgError;
957
958 fn from_str(s: &str) -> Result<Self, Self::Err> {
959 let mut s = &s[..];
960 let node_identifier;
961 let mut path_predicate = Vec::new();
962 let mut absolute_path = None;
963
964 if s.len() == 0 {
965 return Err(ArgError::new("descendant-path"));
966 }
967
968 match s.find(|c: char| c == '[' || c == '/') {
969 Some(pos) => {
970 node_identifier = NodeIdentifier::from_str(&s[..pos])?;
971 s = &s[pos..];
972
973 if s.starts_with('[') {
974 while {
976 let pos = match s.find(']') {
977 Some(p) => Ok(p + 1),
978 None => Err(ArgError::new("descendant-path")),
979 }?;
980
981 path_predicate.push(PathPredicate::from_str(&s[..pos])?);
982 s = &s[pos..];
983
984 s.len() > 0 && s.starts_with('[')
985 } {}
986 }
987
988 if s.len() > 0 {
989 absolute_path = Some(AbsolutePath::from_str(s)?);
990 }
991 }
992 None => {
993 node_identifier = NodeIdentifier::from_str(s)?;
994 }
995 }
996
997 Ok(DescendantPath {
998 node_identifier,
999 path_predicate,
1000 absolute_path,
1001 })
1002 }
1003}
1004
1005#[derive(Debug, Clone, PartialEq, Getters)]
1007pub struct PathPredicate {
1008 path_equality_expr: PathEqualityExpr,
1009}
1010
1011impl FromStr for PathPredicate {
1012 type Err = ArgError;
1013
1014 fn from_str(s: &str) -> Result<Self, Self::Err> {
1015 if !s.starts_with('[') || !s.ends_with(']') {
1016 Err(ArgError::new("path-predicate"))
1017 } else {
1018 Ok(PathPredicate {
1019 path_equality_expr: PathEqualityExpr::from_str(&s[1..s.len() - 1])?,
1020 })
1021 }
1022 }
1023}
1024
1025#[derive(Debug, Clone, PartialEq, Getters)]
1027pub struct PathEqualityExpr {
1028 node_identifier: NodeIdentifier,
1029 path_key_expr: PathKeyExpr,
1030}
1031
1032impl FromStr for PathEqualityExpr {
1033 type Err = ArgError;
1034
1035 fn from_str(s: &str) -> Result<Self, Self::Err> {
1036 match s.find('=') {
1037 Some(p) => Ok(PathEqualityExpr {
1038 node_identifier: NodeIdentifier::from_str(&s[0..p].trim())?,
1039 path_key_expr: PathKeyExpr::from_str(&s[p + 1..].trim())?,
1040 }),
1041 None => Err(ArgError::new("path-equality-expr")),
1042 }
1043 }
1044}
1045
1046#[derive(Debug, Clone, PartialEq, Getters)]
1056pub struct PathKeyExpr {
1057 rel_path_keyexpr: String,
1058}
1059
1060impl FromStr for PathKeyExpr {
1061 type Err = ArgError;
1062
1063 fn from_str(str: &str) -> Result<Self, Self::Err> {
1064 let paths: Vec<_> = str.split("/").map(|s| s.trim()).collect();
1066 if paths.len() < 3 {
1068 return Err(ArgError::new("path-key-expr"));
1069 } else if !is_current_function_invocation(&paths[0]) {
1071 return Err(ArgError::new("path-key-expr"));
1072 } else {
1074 let mut i = 1;
1075
1076 if paths[i] != ".." {
1077 Err(ArgError::new("path-key-expr"))
1078 } else {
1079 i += 1;
1080 while i < paths.len() && paths[i] == ".." {
1081 i += 1;
1082 }
1083 if i >= paths.len() {
1084 return Err(ArgError::new("path-key-expr"));
1085 }
1086
1087 if !is_node_identifier(paths[i]) {
1088 return Err(ArgError::new("path-key-expr"));
1089 }
1090
1091 while i < paths.len() {
1092 if !is_node_identifier(paths[i]) {
1093 return Err(ArgError::new("path-key-expr"));
1094 }
1095 i += 1;
1096 }
1097
1098 Ok(PathKeyExpr {
1099 rel_path_keyexpr: str.to_string(),
1100 })
1101 }
1102 }
1103 }
1104}
1105
1106pub enum IfFeatureToken {
1110 Init,
1111 ParenBegin,
1112 ParenEnd,
1113 Not,
1114 And,
1115 Or,
1116 IdentifierRef(String),
1117 EndOfLine,
1118}
1119
1120pub struct Tokenizer {
1121 str: String,
1122 pos: usize,
1123}
1124
1125impl Tokenizer {
1126 pub fn new(s: String) -> Tokenizer {
1127 Tokenizer { str: s, pos: 0 }
1128 }
1129
1130 pub fn line(&mut self) -> &str {
1131 &self.str[self.pos..]
1132 }
1133
1134 pub fn get_token(&mut self) -> IfFeatureToken {
1135 if let Some(p) = self.line().find(|c: char| !c.is_whitespace()) {
1136 self.pos += p;
1137 }
1138
1139 if self.line().len() == 0 {
1140 IfFeatureToken::EndOfLine
1141 } else if self.line().starts_with('(') {
1142 self.pos += 1;
1143 IfFeatureToken::ParenBegin
1144 } else if self.line().starts_with(')') {
1145 self.pos += 1;
1146 IfFeatureToken::ParenEnd
1147 } else if self.line().starts_with("not") {
1148 self.pos += 3;
1149 IfFeatureToken::Not
1150 } else if self.line().starts_with("and") {
1151 self.pos += 3;
1152 IfFeatureToken::And
1153 } else if self.line().starts_with("or") {
1154 self.pos += 2;
1155 IfFeatureToken::Or
1156 } else {
1157 let p = match self.line().find(|c: char| {
1158 !c.is_alphanumeric() && c != '-' && c != '_' && c != '.' && c != ':'
1159 }) {
1160 Some(p) => p,
1161 None => self.str.len() - self.pos,
1162 };
1163 let token = &self.str[self.pos..self.pos + p];
1164
1165 self.pos += p;
1166 IfFeatureToken::IdentifierRef(token.to_string())
1167 }
1168 }
1169}
1170
1171#[derive(Clone, PartialEq, Getters)]
1173pub struct IfFeatureExpr {
1174 terms: Vec<IfFeatureTerm>,
1175}
1176
1177impl fmt::Debug for IfFeatureExpr {
1178 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1179 write!(f, "{}", self.to_string())
1180 }
1181}
1182
1183impl ToString for IfFeatureExpr {
1184 fn to_string(&self) -> String {
1185 let vec: Vec<_> = self.terms.iter().map(|t| t.to_string()).collect();
1186 format!("{}", vec.join(" or "))
1187 }
1188}
1189
1190impl IfFeatureExpr {
1191 pub fn parse(tokenizer: &mut Tokenizer) -> Result<Self, ArgError> {
1193 let mut terms: Vec<IfFeatureTerm> = Vec::new();
1194 let mut factors: Vec<IfFeatureFactor> = Vec::new();
1195 let mut not: Option<bool> = None;
1196 let mut prev = IfFeatureToken::Init;
1197
1198 loop {
1199 let mut token = tokenizer.get_token();
1200 match token {
1201 IfFeatureToken::Init => {}
1202 IfFeatureToken::ParenBegin => {
1203 match prev {
1204 IfFeatureToken::ParenBegin
1205 | IfFeatureToken::ParenEnd
1206 | IfFeatureToken::IdentifierRef(_) => {
1207 return Err(ArgError::new("if-feature-expr"))
1208 }
1209 _ => {}
1210 }
1211
1212 let expr = Box::new(IfFeatureExpr::parse(tokenizer)?);
1213 factors.push(IfFeatureFactor::IfFeatureExpr((not.take(), expr)));
1214
1215 token = IfFeatureToken::ParenEnd;
1216 }
1217 IfFeatureToken::ParenEnd => {
1218 match prev {
1219 IfFeatureToken::ParenBegin
1220 | IfFeatureToken::Not
1221 | IfFeatureToken::And
1222 | IfFeatureToken::Or => return Err(ArgError::new("if-feature-expr")),
1223 _ => {}
1224 }
1225
1226 break;
1227 }
1228 IfFeatureToken::Or => {
1229 match prev {
1230 IfFeatureToken::Init
1231 | IfFeatureToken::ParenBegin
1232 | IfFeatureToken::Not
1233 | IfFeatureToken::And
1234 | IfFeatureToken::Or => return Err(ArgError::new("if-feature-expr")),
1235 _ => {}
1236 }
1237
1238 terms.push(IfFeatureTerm {
1239 factors: factors.drain(..).collect(),
1240 });
1241 factors = Vec::new();
1242 }
1243 IfFeatureToken::And => match prev {
1244 IfFeatureToken::Init
1245 | IfFeatureToken::ParenBegin
1246 | IfFeatureToken::Not
1247 | IfFeatureToken::And
1248 | IfFeatureToken::Or => return Err(ArgError::new("if-feature-expr")),
1249 _ => {}
1250 },
1251 IfFeatureToken::Not => {
1252 match prev {
1253 IfFeatureToken::ParenEnd
1254 | IfFeatureToken::Not
1255 | IfFeatureToken::IdentifierRef(_) => {
1256 return Err(ArgError::new("if-feature-expr"))
1257 }
1258 _ => {}
1259 }
1260
1261 not.replace(true);
1262 }
1263 IfFeatureToken::IdentifierRef(ref str) => {
1264 match prev {
1265 IfFeatureToken::ParenEnd | IfFeatureToken::IdentifierRef(_) => {
1266 return Err(ArgError::new("if-feature-expr"))
1267 }
1268 _ => {}
1269 }
1270
1271 let identifier_ref = IdentifierRef::from_str(&str)?;
1272 factors.push(IfFeatureFactor::IdentifierRef((not.take(), identifier_ref)));
1273 }
1274 IfFeatureToken::EndOfLine => break,
1275 }
1276
1277 prev = token;
1278 }
1279
1280 terms.push(IfFeatureTerm {
1281 factors: factors.drain(..).collect(),
1282 });
1283 Ok(IfFeatureExpr { terms })
1284 }
1285}
1286
1287impl StmtArg for IfFeatureExpr {
1288 fn parse_arg(parser: &mut Parser) -> Result<Self, YangError> {
1289 let str = parse_string(parser)?;
1290 let mut tokenizer = Tokenizer::new(str);
1291
1292 IfFeatureExpr::parse(&mut tokenizer).map_err(|e| YangError::ArgumentParseError(e.str))
1293 }
1294}
1295
1296#[derive(Debug, Clone, PartialEq, Getters)]
1298pub struct IfFeatureTerm {
1299 factors: Vec<IfFeatureFactor>,
1300}
1301
1302impl ToString for IfFeatureTerm {
1303 fn to_string(&self) -> String {
1304 let vec: Vec<_> = self.factors.iter().map(|f| f.to_string()).collect();
1305 format!("{}", vec.join(" and "))
1306 }
1307}
1308
1309#[derive(Debug, Clone, PartialEq)]
1311pub enum IfFeatureFactor {
1312 IfFeatureExpr((Option<bool>, Box<IfFeatureExpr>)),
1313 IdentifierRef((Option<bool>, IdentifierRef)),
1314}
1315
1316impl ToString for IfFeatureFactor {
1317 fn to_string(&self) -> String {
1318 match self {
1319 IfFeatureFactor::IfFeatureExpr((not, expr)) => {
1320 if let Some(_) = not {
1321 format!("not ({:?})", expr)
1322 } else {
1323 format!("({:?})", expr)
1324 }
1325 }
1326 IfFeatureFactor::IdentifierRef((not, identifier_ref)) => {
1327 if let Some(_) = not {
1328 format!("not {:?}", identifier_ref)
1329 } else {
1330 format!("{:?}", identifier_ref)
1331 }
1332 }
1333 }
1334 }
1335}
1336
1337#[derive(Debug, Clone, PartialEq, Getters)]
1341pub struct RequireInstanceArg {
1342 arg: bool,
1343}
1344
1345impl StmtArg for RequireInstanceArg {
1346 fn parse_arg(parser: &mut Parser) -> Result<Self, YangError> {
1347 let str = parse_string(parser)?;
1348 if str == "true" {
1349 Ok(RequireInstanceArg { arg: true })
1350 } else if str == "false" {
1351 Ok(RequireInstanceArg { arg: false })
1352 } else {
1353 Err(YangError::ArgumentParseError("require-instance-arg"))
1354 }
1355 }
1356}
1357
1358#[derive(Debug, Clone, PartialEq, Getters)]
1362pub struct KeyArg {
1363 keys: Vec<NodeIdentifier>,
1364}
1365
1366impl StmtArg for KeyArg {
1367 fn parse_arg(parser: &mut Parser) -> Result<Self, YangError> {
1368 let str = parse_string(parser)?;
1369 let mut keys = Vec::new();
1370 let mut s = &str[..];
1371
1372 while {
1373 let pos = match s.find(char::is_whitespace) {
1374 Some(p) => p,
1375 None => s.len(),
1376 };
1377
1378 let node_identifier = NodeIdentifier::from_str(&s[..pos])
1379 .map_err(|e| YangError::ArgumentParseError(e.str))?;
1380 keys.push(node_identifier);
1381
1382 s = &s[pos..].trim();
1383 s.len() > 0
1384 } {}
1385
1386 Ok(KeyArg { keys })
1387 }
1388}
1389
1390#[derive(Debug, Clone, PartialEq)]
1394pub enum SchemaNodeid {
1395 Absolute(AbsoluteSchemaNodeid),
1396 Descendant(DescendantSchemaNodeid),
1397}
1398
1399impl StmtArg for SchemaNodeid {
1400 fn parse_arg(parser: &mut Parser) -> Result<Self, YangError> {
1401 let str = parse_string(parser)?;
1402 if str.starts_with('/') {
1403 Ok(SchemaNodeid::Absolute(
1404 AbsoluteSchemaNodeid::from_str(&str)
1405 .map_err(|e| YangError::ArgumentParseError(e.str))?,
1406 ))
1407 } else {
1408 Ok(SchemaNodeid::Descendant(
1409 DescendantSchemaNodeid::from_str(&str)
1410 .map_err(|e| YangError::ArgumentParseError(e.str))?,
1411 ))
1412 }
1413 }
1414}
1415
1416#[derive(Debug, Clone, PartialEq, Getters)]
1417pub struct AbsoluteSchemaNodeid {
1418 nodes: Vec<NodeIdentifier>,
1419}
1420
1421#[derive(Debug, Clone, PartialEq, Getters)]
1422pub struct DescendantSchemaNodeid {
1423 nodes: Vec<NodeIdentifier>,
1424}
1425
1426impl FromStr for AbsoluteSchemaNodeid {
1427 type Err = ArgError;
1428
1429 fn from_str(str: &str) -> Result<Self, Self::Err> {
1430 if let Some(_) = str.find(char::is_whitespace) {
1431 Err(ArgError::new("absolute-schema-nodeid"))
1432 } else if let Some(_) = str.find("//") {
1433 Err(ArgError::new("absolute-schema-nodeid"))
1434 } else if str.starts_with('/') {
1435 let mut nodes: Vec<NodeIdentifier> = Vec::new();
1436 for n in (&str[1..]).split('/') {
1437 nodes.push(NodeIdentifier::from_str(n)?);
1438 }
1439 Ok(AbsoluteSchemaNodeid { nodes })
1440 } else {
1441 Err(ArgError::new("absolute-schema-nodeid"))
1442 }
1443 }
1444}
1445
1446impl FromStr for DescendantSchemaNodeid {
1447 type Err = ArgError;
1448
1449 fn from_str(str: &str) -> Result<Self, Self::Err> {
1450 if let Some(_) = str.find(char::is_whitespace) {
1451 Err(ArgError::new("descendant-schema-nodeid"))
1452 } else if let Some(_) = str.find("//") {
1453 Err(ArgError::new("descendant-schema-nodeid"))
1454 } else if !str.starts_with('/') {
1455 let mut nodes: Vec<NodeIdentifier> = Vec::new();
1456 for n in str.split('/') {
1457 nodes.push(NodeIdentifier::from_str(n)?);
1458 }
1459 Ok(DescendantSchemaNodeid { nodes })
1460 } else {
1461 Err(ArgError::new("descendant-schema-nodeid"))
1462 }
1463 }
1464}
1465
1466impl StmtArg for AbsoluteSchemaNodeid {
1467 fn parse_arg(parser: &mut Parser) -> Result<Self, YangError> {
1468 let str = parse_string(parser)?;
1469
1470 AbsoluteSchemaNodeid::from_str(&str).map_err(|e| YangError::ArgumentParseError(e.str))
1471 }
1472}
1473
1474impl StmtArg for DescendantSchemaNodeid {
1475 fn parse_arg(parser: &mut Parser) -> Result<Self, YangError> {
1476 let str = parse_string(parser)?;
1477
1478 DescendantSchemaNodeid::from_str(&str).map_err(|e| YangError::ArgumentParseError(e.str))
1479 }
1480}
1481
1482impl ToString for AbsoluteSchemaNodeid {
1483 fn to_string(&self) -> String {
1484 format!(
1485 "/{}",
1486 self.nodes
1487 .iter()
1488 .map(|n| n.to_string())
1489 .collect::<Vec<String>>()
1490 .join("/")
1491 )
1492 }
1493}
1494
1495impl ToString for DescendantSchemaNodeid {
1496 fn to_string(&self) -> String {
1497 self.nodes
1498 .iter()
1499 .map(|n| n.to_string())
1500 .collect::<Vec<String>>()
1501 .join("/")
1502 }
1503}
1504
1505#[derive(Debug, Clone, PartialEq, Getters)]
1509pub struct UniqueArg {
1510 nodeids: Vec<DescendantSchemaNodeid>,
1511}
1512
1513impl StmtArg for UniqueArg {
1514 fn parse_arg(parser: &mut Parser) -> Result<Self, YangError> {
1515 let str = parse_string(parser)?;
1516 UniqueArg::from_str(&str).map_err(|e| YangError::ArgumentParseError(e.str))
1517 }
1518}
1519
1520impl FromStr for UniqueArg {
1521 type Err = ArgError;
1522
1523 fn from_str(str: &str) -> Result<Self, Self::Err> {
1524 let mut nodeids = Vec::new();
1525
1526 for n in str.split_whitespace() {
1527 nodeids.push(DescendantSchemaNodeid::from_str(n)?);
1528 }
1529
1530 Ok(UniqueArg { nodeids })
1531 }
1532}
1533
1534pub type RefineArg = DescendantSchemaNodeid;
1536
1537pub type UsesAugmentArg = DescendantSchemaNodeid;
1539
1540pub type AugmentArg = AbsoluteSchemaNodeid;
1542
1543pub type DeviationArg = AbsoluteSchemaNodeid;
1545
1546#[cfg(test)]
1547mod tests {
1548 use super::*;
1549
1550 #[test]
1551 pub fn test_identifier() {
1552 let s = " hello-world ";
1553 let mut parser = Parser::new(s.to_string());
1554
1555 match Identifier::parse_arg(&mut parser) {
1556 Ok(arg) => assert_eq!(
1557 arg,
1558 Identifier {
1559 str: String::from("hello-world")
1560 }
1561 ),
1562 Err(err) => panic!("{:?}", err.to_string()),
1563 }
1564
1565 let s = " _123.IdEnT.456-789_ ";
1566 let mut parser = Parser::new(s.to_string());
1567
1568 match Identifier::parse_arg(&mut parser) {
1569 Ok(arg) => assert_eq!(
1570 arg,
1571 Identifier {
1572 str: String::from("_123.IdEnT.456-789_")
1573 }
1574 ),
1575 Err(err) => panic!("{:?}", err.to_string()),
1576 }
1577
1578 let s = " 123 ";
1579 let mut parser = Parser::new(s.to_string());
1580
1581 match Identifier::parse_arg(&mut parser) {
1582 Ok(_) => assert!(false),
1583 Err(err) => assert_eq!(err.to_string(), "Argument parse error identifier"),
1584 }
1585
1586 let s = " 123$ ";
1587 let mut parser = Parser::new(s.to_string());
1588
1589 match Identifier::parse_arg(&mut parser) {
1590 Ok(_) => assert!(false),
1591 Err(err) => assert_eq!(err.to_string(), "Argument parse error identifier"),
1592 }
1593 }
1594
1595 #[test]
1596 pub fn test_identifier_ref() {
1597 let s = " prefix:hello-world ";
1598 let mut parser = Parser::new(s.to_string());
1599
1600 match IdentifierRef::parse_arg(&mut parser) {
1601 Ok(arg) => assert_eq!(arg.to_string(), "prefix:hello-world"),
1602 Err(err) => panic!("{:?}", err.to_string()),
1603 }
1604
1605 let s = " _prefix_:_123.IdEnT.456-789_ ";
1606 let mut parser = Parser::new(s.to_string());
1607
1608 match IdentifierRef::parse_arg(&mut parser) {
1609 Ok(arg) => assert_eq!(arg.to_string(), "_prefix_:_123.IdEnT.456-789_"),
1610 Err(err) => panic!("{:?}", err.to_string()),
1611 }
1612
1613 let s = " 123:456 ";
1614 let mut parser = Parser::new(s.to_string());
1615
1616 match IdentifierRef::parse_arg(&mut parser) {
1617 Ok(_) => assert!(false),
1618 Err(err) => assert_eq!(err.to_string(), "Argument parse error identifier"),
1619 }
1620
1621 let s = " _123:_456 ";
1622 let mut parser = Parser::new(s.to_string());
1623
1624 match IdentifierRef::parse_arg(&mut parser) {
1625 Ok(arg) => assert_eq!(arg.to_string(), "_123:_456"),
1626 Err(err) => panic!("{:?}", err.to_string()),
1627 }
1628
1629 let s = " _123: ";
1630 let mut parser = Parser::new(s.to_string());
1631
1632 match IdentifierRef::parse_arg(&mut parser) {
1633 Ok(_) => assert!(false),
1634 Err(err) => assert_eq!(err.to_string(), "Argument parse error identifier"),
1635 }
1636 }
1637
1638 #[test]
1639 pub fn test_date_arg() {
1640 let s = " 2021-08-01 ";
1641 let mut parser = Parser::new(s.to_string());
1642
1643 match DateArg::parse_arg(&mut parser) {
1644 Ok(arg) => assert_eq!(arg.to_string(), "2021-08-01"),
1645 Err(err) => panic!("{:?}", err.to_string()),
1646 }
1647
1648 let s = " 2021-8-1 ";
1649 let mut parser = Parser::new(s.to_string());
1650
1651 match DateArg::parse_arg(&mut parser) {
1652 Ok(_) => assert!(false),
1653 Err(err) => assert_eq!(err.to_string(), "Argument parse error date-arg"),
1654 }
1655
1656 let s = " 08-01-2021 ";
1657 let mut parser = Parser::new(s.to_string());
1658
1659 match DateArg::parse_arg(&mut parser) {
1660 Ok(_) => assert!(false),
1661 Err(err) => assert_eq!(err.to_string(), "Argument parse error date-arg"),
1662 }
1663
1664 let s = " 2021-08-0x ";
1665 let mut parser = Parser::new(s.to_string());
1666
1667 match DateArg::parse_arg(&mut parser) {
1668 Ok(_) => assert!(false),
1669 Err(err) => assert_eq!(err.to_string(), "Argument parse error date-arg"),
1670 }
1671 }
1672
1673 #[test]
1674 pub fn test_fraction_digits_arg() {
1675 let s = "18";
1676 let mut parser = Parser::new(s.to_string());
1677
1678 match FractionDigitsArg::parse_arg(&mut parser) {
1679 Ok(arg) => assert_eq!(arg.digits(), &18),
1680 Err(err) => panic!("{:?}", err.to_string()),
1681 }
1682
1683 let s = "0";
1684 let mut parser = Parser::new(s.to_string());
1685
1686 match FractionDigitsArg::parse_arg(&mut parser) {
1687 Ok(_) => assert!(false),
1688 Err(err) => assert_eq!(err.to_string(), "Argument parse error fraction-digits-arg"),
1689 }
1690
1691 let s = "19";
1692 let mut parser = Parser::new(s.to_string());
1693
1694 match FractionDigitsArg::parse_arg(&mut parser) {
1695 Ok(_) => assert!(false),
1696 Err(err) => assert_eq!(err.to_string(), "Argument parse error fraction-digits-arg"),
1697 }
1698 }
1699
1700 #[test]
1701 pub fn test_range_arg() {
1702 let s = r#""1..10""#;
1703 let mut parser = Parser::new(s.to_string());
1704
1705 match RangeArg::parse_arg(&mut parser) {
1706 Ok(arg) => assert_eq!(
1707 arg,
1708 RangeArg {
1709 parts: vec![(RangeBoundary::Integer(1), Some(RangeBoundary::Integer(10)))]
1710 }
1711 ),
1712 Err(err) => panic!("{:?}", err.to_string()),
1713 }
1714
1715 let s = r#""1 .. 10 | 21..30""#;
1716 let mut parser = Parser::new(s.to_string());
1717
1718 match RangeArg::parse_arg(&mut parser) {
1719 Ok(arg) => assert_eq!(
1720 arg,
1721 RangeArg {
1722 parts: vec![
1723 (RangeBoundary::Integer(1), Some(RangeBoundary::Integer(10))),
1724 (RangeBoundary::Integer(21), Some(RangeBoundary::Integer(30))),
1725 ]
1726 }
1727 ),
1728 Err(err) => panic!("{:?}", err.to_string()),
1729 }
1730
1731 let s = r#""min..max""#;
1732 let mut parser = Parser::new(s.to_string());
1733
1734 match RangeArg::parse_arg(&mut parser) {
1735 Ok(arg) => assert_eq!(
1736 arg,
1737 RangeArg {
1738 parts: vec![(RangeBoundary::Min, Some(RangeBoundary::Max)),]
1739 }
1740 ),
1741 Err(err) => panic!("{:?}", err.to_string()),
1742 }
1743
1744 let s = r#""min..""#;
1745 let mut parser = Parser::new(s.to_string());
1746
1747 match RangeArg::parse_arg(&mut parser) {
1748 Ok(_) => assert!(false),
1749 Err(err) => assert_eq!(err.to_string(), "Argument parse error range-arg"),
1750 }
1751
1752 let s = r#""1.01 .. 1.99""#;
1753 let mut parser = Parser::new(s.to_string());
1754
1755 match RangeArg::parse_arg(&mut parser) {
1756 Ok(arg) => assert_eq!(
1757 arg,
1758 RangeArg {
1759 parts: vec![(
1760 RangeBoundary::Decimal(1.01),
1761 Some(RangeBoundary::Decimal(1.99))
1762 )]
1763 }
1764 ),
1765 Err(err) => panic!("{:?}", err.to_string()),
1766 }
1767 }
1768
1769 #[test]
1770 pub fn test_length_arg() {
1771 let s = r#""1..10""#;
1772 let mut parser = Parser::new(s.to_string());
1773
1774 match LengthArg::parse_arg(&mut parser) {
1775 Ok(arg) => assert_eq!(
1776 arg,
1777 LengthArg {
1778 parts: vec![(
1779 LengthBoundary::Integer(1),
1780 Some(LengthBoundary::Integer(10))
1781 )]
1782 }
1783 ),
1784 Err(err) => panic!("{:?}", err.to_string()),
1785 }
1786
1787 let s = r#""1 .. 10 | 21..30""#;
1788 let mut parser = Parser::new(s.to_string());
1789
1790 match LengthArg::parse_arg(&mut parser) {
1791 Ok(arg) => assert_eq!(
1792 arg,
1793 LengthArg {
1794 parts: vec![
1795 (
1796 LengthBoundary::Integer(1),
1797 Some(LengthBoundary::Integer(10))
1798 ),
1799 (
1800 LengthBoundary::Integer(21),
1801 Some(LengthBoundary::Integer(30))
1802 ),
1803 ]
1804 }
1805 ),
1806 Err(err) => panic!("{:?}", err.to_string()),
1807 }
1808
1809 let s = r#""min..max""#;
1810 let mut parser = Parser::new(s.to_string());
1811
1812 match LengthArg::parse_arg(&mut parser) {
1813 Ok(arg) => assert_eq!(
1814 arg,
1815 LengthArg {
1816 parts: vec![(LengthBoundary::Min, Some(LengthBoundary::Max)),]
1817 }
1818 ),
1819 Err(err) => panic!("{:?}", err.to_string()),
1820 }
1821
1822 let s = r#""min..""#;
1823 let mut parser = Parser::new(s.to_string());
1824
1825 match LengthArg::parse_arg(&mut parser) {
1826 Ok(_) => assert!(false),
1827 Err(err) => assert_eq!(err.to_string(), "Argument parse error length-arg"),
1828 }
1829 }
1830
1831 #[test]
1832 pub fn test_path_key_expr() {
1833 let s = "current()/../node";
1834 match PathKeyExpr::from_str(s) {
1835 Ok(arg) => assert_eq!(
1836 arg,
1837 PathKeyExpr {
1838 rel_path_keyexpr: "current()/../node".to_string()
1839 }
1840 ),
1841 Err(err) => panic!("{:?}", err.to_string()),
1842 }
1843
1844 let s = "current()/../../../node";
1845 match PathKeyExpr::from_str(s) {
1846 Ok(arg) => assert_eq!(
1847 arg,
1848 PathKeyExpr {
1849 rel_path_keyexpr: "current()/../../../node".to_string()
1850 }
1851 ),
1852 Err(err) => panic!("{:?}", err.to_string()),
1853 }
1854
1855 let s = "current()/../../../node/node/node";
1856 match PathKeyExpr::from_str(s) {
1857 Ok(arg) => assert_eq!(
1858 arg,
1859 PathKeyExpr {
1860 rel_path_keyexpr: "current()/../../../node/node/node".to_string()
1861 }
1862 ),
1863 Err(err) => panic!("{:?}", err.to_string()),
1864 }
1865
1866 let s = "current ( ) / .. / .. / .. / node / node / node ";
1867 match PathKeyExpr::from_str(s) {
1868 Ok(arg) => assert_eq!(
1869 arg,
1870 PathKeyExpr {
1871 rel_path_keyexpr: "current ( ) / .. / .. / .. / node / node / node "
1872 .to_string()
1873 }
1874 ),
1875 Err(err) => panic!("{:?}", err.to_string()),
1876 }
1877
1878 let s = "current()/..";
1879 match PathKeyExpr::from_str(s) {
1880 Ok(_) => assert!(false),
1881 Err(err) => assert_eq!(err.to_string(), "Arg error: path-key-expr"),
1882 }
1883
1884 let s = "current()/node/node/node";
1885 match PathKeyExpr::from_str(s) {
1886 Ok(_) => assert!(false),
1887 Err(err) => assert_eq!(err.to_string(), "Arg error: path-key-expr"),
1888 }
1889 }
1890
1891 #[test]
1892 pub fn test_absolute_path() {
1893 let s = "/node1/node2[id=current()/../rel1/rel2]";
1894 let path = AbsolutePath {
1895 nodes: vec![
1896 PathNode {
1897 node_identifier: NodeIdentifier::from_str("node1").unwrap(),
1898 path_predicate: vec![],
1899 },
1900 PathNode {
1901 node_identifier: NodeIdentifier::from_str("node2").unwrap(),
1902 path_predicate: vec![PathPredicate {
1903 path_equality_expr: PathEqualityExpr {
1904 node_identifier: NodeIdentifier::from_str("id").unwrap(),
1905 path_key_expr: PathKeyExpr {
1906 rel_path_keyexpr: "current()/../rel1/rel2".to_string(),
1907 },
1908 },
1909 }],
1910 },
1911 ],
1912 };
1913
1914 match AbsolutePath::from_str(s) {
1915 Ok(p) => assert_eq!(p, path),
1916 Err(err) => panic!("{:?}", err.to_string()),
1917 }
1918
1919 let s =
1920 "/node1/node2[id1=current()/../rel1/rel2][prefix:id2=current()/../../rel3/rel4]/node3";
1921 let path = AbsolutePath {
1922 nodes: vec![
1923 PathNode {
1924 node_identifier: NodeIdentifier::from_str("node1").unwrap(),
1925 path_predicate: vec![],
1926 },
1927 PathNode {
1928 node_identifier: NodeIdentifier::from_str("node2").unwrap(),
1929 path_predicate: vec![
1930 PathPredicate {
1931 path_equality_expr: PathEqualityExpr {
1932 node_identifier: NodeIdentifier::from_str("id1").unwrap(),
1933 path_key_expr: PathKeyExpr {
1934 rel_path_keyexpr: "current()/../rel1/rel2".to_string(),
1935 },
1936 },
1937 },
1938 PathPredicate {
1939 path_equality_expr: PathEqualityExpr {
1940 node_identifier: NodeIdentifier::from_str("prefix:id2").unwrap(),
1941 path_key_expr: PathKeyExpr {
1942 rel_path_keyexpr: "current()/../../rel3/rel4".to_string(),
1943 },
1944 },
1945 },
1946 ],
1947 },
1948 PathNode {
1949 node_identifier: NodeIdentifier::from_str("node3").unwrap(),
1950 path_predicate: vec![],
1951 },
1952 ],
1953 };
1954
1955 match AbsolutePath::from_str(s) {
1956 Ok(p) => assert_eq!(p, path),
1957 Err(err) => panic!("{:?}", err.to_string()),
1958 }
1959 }
1960
1961 #[test]
1962 pub fn test_descendant_path() {
1963 let s = "node0/node1/node2[id=current()/../rel1/rel2]";
1964
1965 let absolute_path = AbsolutePath {
1966 nodes: vec![
1967 PathNode {
1968 node_identifier: NodeIdentifier::from_str("node1").unwrap(),
1969 path_predicate: vec![],
1970 },
1971 PathNode {
1972 node_identifier: NodeIdentifier::from_str("node2").unwrap(),
1973 path_predicate: vec![PathPredicate {
1974 path_equality_expr: PathEqualityExpr {
1975 node_identifier: NodeIdentifier::from_str("id").unwrap(),
1976 path_key_expr: PathKeyExpr {
1977 rel_path_keyexpr: "current()/../rel1/rel2".to_string(),
1978 },
1979 },
1980 }],
1981 },
1982 ],
1983 };
1984 let descendant_path = DescendantPath {
1985 node_identifier: NodeIdentifier::from_str("node0").unwrap(),
1986 path_predicate: vec![],
1987 absolute_path: Some(absolute_path),
1988 };
1989
1990 match DescendantPath::from_str(s) {
1991 Ok(p) => assert_eq!(p, descendant_path),
1992 Err(err) => panic!("{:?}", err.to_string()),
1993 }
1994 }
1995
1996 #[test]
1997 pub fn test_relative_path() {
1998 let s = "../../node0/node1/node2";
1999
2000 let absolute_path = AbsolutePath {
2001 nodes: vec![
2002 PathNode {
2003 node_identifier: NodeIdentifier::from_str("node1").unwrap(),
2004 path_predicate: vec![],
2005 },
2006 PathNode {
2007 node_identifier: NodeIdentifier::from_str("node2").unwrap(),
2008 path_predicate: vec![],
2009 },
2010 ],
2011 };
2012
2013 let descendant_path = DescendantPath {
2014 node_identifier: NodeIdentifier::from_str("node0").unwrap(),
2015 path_predicate: vec![],
2016 absolute_path: Some(absolute_path),
2017 };
2018
2019 let relative_path = RelativePath {
2020 up: 2u32,
2021 descendant_path,
2022 };
2023
2024 match RelativePath::from_str(s) {
2025 Ok(p) => assert_eq!(p, relative_path),
2026 Err(err) => panic!("{:?}", err.to_string()),
2027 }
2028 }
2029
2030 #[test]
2031 pub fn test_if_feature_expr() {
2032 let s = r#""p1:id1 and p1:id2 or (p2:id3 and p2:id4) or not p3:id5""#;
2033 let mut parser = Parser::new(s.to_string());
2034
2035 match IfFeatureExpr::parse_arg(&mut parser) {
2036 Ok(expr) => assert_eq!(
2037 format!("{:?}", expr),
2038 "p1:id1 and p1:id2 or (p2:id3 and p2:id4) or not p3:id5"
2039 ),
2040 Err(_) => panic!(),
2041 }
2042
2043 let s = r#""p1:id1 p1:id2""#;
2044 let mut parser = Parser::new(s.to_string());
2045
2046 match IfFeatureExpr::parse_arg(&mut parser) {
2047 Ok(expr) => panic!("{:?}", expr),
2048 Err(err) => assert_eq!(err.to_string(), "Argument parse error if-feature-expr"),
2049 }
2050 }
2051
2052 #[test]
2053 pub fn test_key_arg() {
2054 let s = r#""p1:id1 p1:id2 p2:id3 id4 id5""#;
2055 let mut parser = Parser::new(s.to_string());
2056
2057 match KeyArg::parse_arg(&mut parser) {
2058 Ok(arg) => assert_eq!(
2059 arg,
2060 KeyArg {
2061 keys: vec![
2062 NodeIdentifier::from_str("p1:id1").unwrap(),
2063 NodeIdentifier::from_str("p1:id2").unwrap(),
2064 NodeIdentifier::from_str("p2:id3").unwrap(),
2065 NodeIdentifier::from_str("id4").unwrap(),
2066 NodeIdentifier::from_str("id5").unwrap(),
2067 ]
2068 }
2069 ),
2070 Err(err) => panic!("{}", err.to_string()),
2071 }
2072 }
2073
2074 #[test]
2075 pub fn test_absolute_schema_nodeid() {
2076 let s = r#""/id1/id2/id3""#;
2077 let mut parser = Parser::new(s.to_string());
2078
2079 match AbsoluteSchemaNodeid::parse_arg(&mut parser) {
2080 Ok(arg) => {
2081 assert_eq!(arg.to_string(), "/id1/id2/id3");
2082 assert_eq!(arg.nodes.len(), 3);
2083 }
2084 Err(err) => panic!("{}", err.to_string()),
2085 }
2086 }
2087
2088 #[test]
2089 pub fn test_descendant_schema_nodeid() {
2090 let s = r#""id1/id2/id3""#;
2091 let mut parser = Parser::new(s.to_string());
2092
2093 match DescendantSchemaNodeid::parse_arg(&mut parser) {
2094 Ok(arg) => {
2095 assert_eq!(arg.to_string(), "id1/id2/id3");
2096 assert_eq!(arg.nodes.len(), 3);
2097 }
2098 Err(err) => panic!("{}", err.to_string()),
2099 }
2100 }
2101}