1#[derive(Clone, Debug, PartialEq, Eq)]
17pub enum Segment {
18 Key(String),
20 Index(usize),
22}
23
24impl Segment {
25 pub fn is_key(&self) -> bool {
27 matches!(self, Self::Key(_))
28 }
29
30 pub fn is_index(&self) -> bool {
32 matches!(self, Self::Index(_))
33 }
34
35 pub fn as_key(&self) -> Option<&str> {
37 match self {
38 Self::Key(k) => Some(k),
39 _ => None,
40 }
41 }
42
43 pub fn as_index(&self) -> Option<usize> {
45 match self {
46 Self::Index(i) => Some(*i),
47 _ => None,
48 }
49 }
50}
51
52impl From<String> for Segment {
53 fn from(key: String) -> Self {
54 Self::Key(key)
55 }
56}
57
58impl From<&str> for Segment {
59 fn from(key: &str) -> Self {
60 Self::Key(key.to_owned())
61 }
62}
63
64impl From<usize> for Segment {
65 fn from(index: usize) -> Self {
66 Self::Index(index)
67 }
68}
69
70impl std::fmt::Display for Segment {
71 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
72 match self {
73 Self::Key(k) => write!(f, "{}", k),
74 Self::Index(i) => write!(f, "{}", i),
75 }
76 }
77}
78
79#[cfg(test)]
80mod tests {
81 use super::*;
82
83 mod predicates {
84 use super::*;
85
86 #[test]
87 fn key_is_key() {
88 let seg: Segment = "foo".into();
89 assert!(seg.is_key());
90 assert!(!seg.is_index());
91 }
92
93 #[test]
94 fn index_is_index() {
95 let seg: Segment = 0usize.into();
96 assert!(seg.is_index());
97 assert!(!seg.is_key());
98 }
99 }
100
101 mod conversions {
102 use super::*;
103
104 #[test]
105 fn as_key_some() {
106 let seg: Segment = "foo".into();
107 assert_eq!(seg.as_key(), Some("foo"));
108 }
109
110 #[test]
111 fn as_key_none() {
112 let seg: Segment = 0usize.into();
113 assert!(seg.as_key().is_none());
114 }
115
116 #[test]
117 fn as_index_some() {
118 let seg: Segment = 3usize.into();
119 assert_eq!(seg.as_index(), Some(3));
120 }
121
122 #[test]
123 fn as_index_none() {
124 let seg: Segment = "foo".into();
125 assert!(seg.as_index().is_none());
126 }
127 }
128
129 mod display {
130 use super::*;
131
132 #[test]
133 fn key_display() {
134 let seg: Segment = "serde".into();
135 assert_eq!(seg.to_string(), "serde");
136 }
137
138 #[test]
139 fn index_display() {
140 let seg: Segment = 42usize.into();
141 assert_eq!(seg.to_string(), "42");
142 }
143 }
144
145 mod from {
146 use super::*;
147
148 #[test]
149 fn from_str() {
150 let seg: Segment = "hello".into();
151 assert_eq!(seg, Segment::Key("hello".into()));
152 }
153
154 #[test]
155 fn from_string() {
156 let seg: Segment = String::from("hello").into();
157 assert_eq!(seg, Segment::Key("hello".into()));
158 }
159
160 #[test]
161 fn from_usize() {
162 let seg: Segment = 5usize.into();
163 assert_eq!(seg, Segment::Index(5));
164 }
165 }
166}