1use std::{
2 borrow::Cow,
3 fmt,
4 num::{
5 NonZeroUsize,
6 ParseIntError,
7 },
8 str::FromStr,
9 string::ToString,
10};
11
12#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
15pub struct Index(pub(crate) usize);
16
17impl Index {
18 #[must_use]
19 pub fn new(index: usize) -> Index {
21 Index(index)
22 }
23}
24
25impl From<Index> for usize {
26 fn from(index: Index) -> usize {
27 index.0
28 }
29}
30
31impl fmt::Display for Index {
32 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
33 write!(f, "Index ({})", self.0)
34 }
35}
36
37impl FromStr for Index {
38 type Err = ParseIntError;
39
40 fn from_str(s: &str) -> Result<Self, Self::Err> {
41 Ok(Index(s.parse::<usize>()?))
42 }
43}
44
45#[derive(Debug, Clone, PartialEq, Eq)]
48pub struct Range(pub(crate) Option<Index>, pub(crate) Option<Index>);
49
50impl Range {
51 #[must_use]
52 pub fn new(start: Option<Index>, end: Option<Index>) -> Range {
54 Range(start, end)
55 }
56
57 #[must_use]
58 pub fn to_boundaries(&self, len: NonZeroUsize) -> (usize, usize) {
62 let start = self.0.unwrap_or(Index(0));
63 let end = self.1.unwrap_or(Index(len.get() - 1));
64
65 (start.0, end.0)
66 }
67}
68
69impl fmt::Display for Range {
70 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
71 let format_bound = |bound: &Option<Index>| match bound {
72 Some(index) => index.to_string(),
73 None => String::new(),
74 };
75
76 write!(
77 f,
78 "Range [{}:{}]",
79 format_bound(&self.0),
80 format_bound(&self.1)
81 )
82 }
83}
84
85#[derive(Debug, Clone, PartialEq, Eq)]
89pub struct Lens<'a>(pub(crate) Vec<Token<'a>>, pub(crate) Option<LensValue<'a>>);
90
91impl<'a> Lens<'a> {
92 #[must_use]
93 pub fn new(tokens: &[Token<'a>], value: Option<LensValue<'a>>) -> Lens<'a> {
95 Lens(tokens.to_vec(), value)
96 }
97
98 #[must_use]
99 pub fn get(&self) -> (Vec<Token<'a>>, Option<LensValue<'a>>) {
101 (self.0.clone(), self.1.clone())
102 }
103
104 #[must_use]
105 pub fn get_ref(&self) -> (&[Token<'a>], Option<&LensValue<'a>>) {
107 (&self.0, self.1.as_ref())
108 }
109}
110
111impl fmt::Display for Lens<'_> {
112 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
113 write!(
114 f,
115 "{}{}",
116 self.0.stringify(),
117 match &self.1 {
118 Some(lens_value) => {
119 lens_value.to_string()
120 }
121 None => String::new(),
122 }
123 )
124 }
125}
126
127#[derive(Debug, Clone, PartialEq, Eq)]
129pub enum LensValue<'a> {
130 Bool(bool),
132 Null,
134 Number(usize),
136 String(Cow<'a, str>),
138}
139
140impl fmt::Display for LensValue<'_> {
141 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
142 match self {
143 LensValue::Bool(boolean) => {
144 write!(f, "{boolean}")
145 }
146 LensValue::Null => {
147 write!(f, "null")
148 }
149 LensValue::Number(number) => {
150 write!(f, "{number}")
151 }
152 LensValue::String(string) => write!(f, "{string}"),
153 }
154 }
155}
156
157#[derive(Debug, Clone, PartialEq, Eq)]
159pub enum Token<'a> {
160 ArrayIndexSelector(Vec<Index>),
162 ArrayRangeSelector(Range),
164 FlattenOperator,
166 KeyOperator,
168 GroupSeparator,
170 KeySelector(Cow<'a, str>),
172 LensSelector(Vec<Lens<'a>>),
174 MultiKeySelector(Vec<Cow<'a, str>>),
176 ObjectIndexSelector(Vec<Index>),
178 ObjectRangeSelector(Range),
180 PipeInOperator,
182 PipeOutOperator,
184 TruncateOperator,
186}
187
188impl<'a> Token<'a> {
189 fn get_name(&self) -> &'a str {
190 match self {
191 Token::ArrayIndexSelector(_) => "Array Index Selector",
192 Token::ArrayRangeSelector(_) => "Array Range Selector",
193 Token::FlattenOperator => "Flatten Operator",
194 Token::KeyOperator => "Key Operator",
195 Token::GroupSeparator => "Group Separator",
196 Token::KeySelector(_) => "Key Selector",
197 Token::LensSelector(_) => "Lens Selector",
198 Token::MultiKeySelector(_) => "Multi Key Selector",
199 Token::ObjectIndexSelector(_) => "Object Index Selector",
200 Token::ObjectRangeSelector(_) => "Object Range Selector",
201 Token::PipeInOperator => "Pipe In Operator",
202 Token::PipeOutOperator => "Pipe Out Operator",
203 Token::TruncateOperator => "Truncate Operator",
204 }
205 }
206}
207
208impl fmt::Display for Token<'_> {
209 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
210 match self {
211 Token::ArrayIndexSelector(indexes) | Token::ObjectIndexSelector(indexes) => {
212 let formatted_indexes = indexes
213 .iter()
214 .map(ToString::to_string)
215 .collect::<Vec<String>>()
216 .join(", ");
217
218 write!(f, "{} [{formatted_indexes}]", self.get_name())
219 }
220 Token::ArrayRangeSelector(range) | Token::ObjectRangeSelector(range) => {
221 write!(f, "{} {}", self.get_name(), range)
222 }
223 Token::KeySelector(key) => {
224 write!(f, r#"{} "{key}""#, self.get_name())
225 }
226 Token::LensSelector(lenses) => {
227 let formatted_indexes = lenses
228 .iter()
229 .map(ToString::to_string)
230 .collect::<Vec<String>>()
231 .join(", ");
232
233 write!(f, "{} [{formatted_indexes}]", self.get_name())
234 }
235 Token::MultiKeySelector(multi_key) => {
236 let formatted_keys = multi_key
237 .iter()
238 .map(AsRef::as_ref)
239 .collect::<Vec<&str>>()
240 .join(", ");
241
242 write!(f, "{} {formatted_keys}", self.get_name())
243 }
244 Token::FlattenOperator
245 | Token::KeyOperator
246 | Token::GroupSeparator
247 | Token::PipeInOperator
248 | Token::PipeOutOperator
249 | Token::TruncateOperator => {
250 write!(f, "{}", self.get_name())
251 }
252 }
253 }
254}
255
256pub trait View {
258 fn stringify(&self) -> String;
260}
261
262impl<'a, T: AsRef<[Token<'a>]>> View for T {
263 fn stringify(&self) -> String {
264 self.as_ref()
265 .iter()
266 .map(ToString::to_string)
267 .collect::<Vec<String>>()
268 .join(", ")
269 }
270}