eure_document/parse/
variant_path.rs1extern crate alloc;
4
5use alloc::fmt;
6use alloc::vec::Vec;
7use core::str::FromStr;
8
9use crate::identifier::{Identifier, IdentifierError};
10
11#[derive(Debug, Clone, PartialEq, Eq)]
15pub struct VariantPath(Vec<Identifier>);
16
17impl VariantPath {
18 pub fn new(segments: Vec<Identifier>) -> Self {
20 Self(segments)
21 }
22
23 pub fn empty() -> Self {
25 Self(Vec::new())
26 }
27
28 pub fn parse(s: &str) -> Result<Self, IdentifierError> {
30 let segments: Result<Vec<_>, _> =
31 s.split('.').map(|seg| seg.parse::<Identifier>()).collect();
32 segments.map(Self)
33 }
34
35 pub fn first(&self) -> Option<&Identifier> {
37 self.0.first()
38 }
39
40 pub fn rest(&self) -> Option<Self> {
42 if self.0.len() > 1 {
43 Some(Self(self.0[1..].to_vec()))
44 } else {
45 None
46 }
47 }
48
49 pub fn is_empty(&self) -> bool {
51 self.0.is_empty()
52 }
53
54 pub fn is_single(&self) -> bool {
56 self.0.len() == 1
57 }
58
59 pub fn len(&self) -> usize {
61 self.0.len()
62 }
63
64 pub fn segments(&self) -> &[Identifier] {
66 &self.0
67 }
68}
69
70impl FromStr for VariantPath {
71 type Err = IdentifierError;
72
73 fn from_str(s: &str) -> Result<Self, Self::Err> {
74 Self::parse(s)
75 }
76}
77
78impl fmt::Display for VariantPath {
79 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80 let mut first = true;
81 for seg in &self.0 {
82 if !first {
83 write!(f, ".")?;
84 }
85 write!(f, "{}", seg)?;
86 first = false;
87 }
88 Ok(())
89 }
90}
91
92#[cfg(test)]
93mod tests {
94 use super::*;
95 use alloc::string::ToString;
96
97 #[test]
98 fn test_parse_single() {
99 let path: VariantPath = "ok".parse().unwrap();
100 assert!(path.is_single());
101 assert_eq!(path.first().unwrap().as_ref(), "ok");
102 assert!(path.rest().is_none());
103 }
104
105 #[test]
106 fn test_parse_nested() {
107 let path: VariantPath = "ok.some.left".parse().unwrap();
108 assert!(!path.is_single());
109 assert_eq!(path.len(), 3);
110 assert_eq!(path.first().unwrap().as_ref(), "ok");
111
112 let rest = path.rest().unwrap();
113 assert_eq!(rest.len(), 2);
114 assert_eq!(rest.first().unwrap().as_ref(), "some");
115
116 let rest2 = rest.rest().unwrap();
117 assert!(rest2.is_single());
118 assert_eq!(rest2.first().unwrap().as_ref(), "left");
119 assert!(rest2.rest().is_none());
120 }
121
122 #[test]
123 fn test_display() {
124 let path: VariantPath = "ok.some.left".parse().unwrap();
125 assert_eq!(path.to_string(), "ok.some.left");
126 }
127
128 #[test]
129 fn test_invalid_identifier() {
130 let result = VariantPath::parse("ok.123invalid");
131 assert!(result.is_err());
132 }
133}