json_api/value/fields/path.rs
1use std::borrow::Borrow;
2use std::fmt::{self, Display, Formatter};
3use std::iter::{Extend, FromIterator};
4use std::ops::Deref;
5use std::slice::Iter;
6use std::str::FromStr;
7
8use serde::de::{Deserialize, Deserializer};
9use serde::ser::{Serialize, Serializer};
10
11use error::Error;
12use sealed::Sealed;
13use value::{Key, Stringify};
14
15/// Represents a dot-separated list of member names.
16///
17/// See also: [relationship path].
18///
19/// [relationship path]: http://jsonapi.org/format/#fetching-includes
20#[derive(Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
21pub struct Path(Vec<Key>);
22
23impl Path {
24 /// Constructs a new, empty `Path`.
25 pub fn new() -> Self {
26 Default::default()
27 }
28
29 /// Constructs a new, empty `Path` with the specified capacity.
30 ///
31 /// # Example
32 ///
33 /// ```
34 /// # extern crate json_api;
35 /// #
36 /// # use json_api::Error;
37 /// # use json_api::value::Path;
38 /// #
39 /// # fn example() -> Result<(), Error> {
40 /// let mut path = Path::with_capacity(2);
41 ///
42 /// path.push("a".parse()?);
43 /// path.push("b".parse()?);
44 ///
45 /// // The next push will require reallocation...
46 /// path.push("c".parse()?);
47 /// #
48 /// # Ok(())
49 /// # }
50 /// #
51 /// # fn main() {
52 /// # example().unwrap();
53 /// # }
54 /// ```
55 pub fn with_capacity(capacity: usize) -> Self {
56 Path(Vec::with_capacity(capacity))
57 }
58
59 /// Returns the number of keys the path can hold without reallocating.
60 ///
61 /// # Example
62 ///
63 /// ```
64 /// # extern crate json_api;
65 /// #
66 /// # use json_api::value::Path;
67 /// #
68 /// # fn main() {
69 /// let path = Path::with_capacity(2);
70 /// assert_eq!(path.capacity(), 2);
71 /// # }
72 /// ```
73 pub fn capacity(&self) -> usize {
74 self.0.capacity()
75 }
76
77 /// Returns the number of chars in a `Path`.
78 ///
79 /// # Example
80 ///
81 /// ```
82 /// # extern crate json_api;
83 /// #
84 /// # use std::str::FromStr;
85 /// #
86 /// # use json_api::Error;
87 /// # use json_api::value::Path;
88 /// #
89 /// # fn example() -> Result<(), Error> {
90 /// let path = Path::from_str("authors.name")?;
91 ///
92 /// assert_eq!(path.len(), 2);
93 /// assert_eq!(path.char_count(), 12);
94 /// #
95 /// # Ok(())
96 /// # }
97 /// #
98 /// # fn main() {
99 /// # example().unwrap();
100 /// # }
101 /// ```
102 pub fn char_count(&self) -> usize {
103 let keys = &self.0;
104 let count = keys.len();
105
106 if count > 0 {
107 keys.iter()
108 .map(|key| key.len())
109 .fold(count - 1, |prev, next| prev + next)
110 } else {
111 count
112 }
113 }
114
115 /// Removes and returns a `Key` to the back of a `Path`.
116 ///
117 /// # Example
118 ///
119 /// ```
120 /// # extern crate json_api;
121 /// #
122 /// # use std::str::FromStr;
123 /// #
124 /// # use json_api::Error;
125 /// # use json_api::value::Path;
126 /// #
127 /// # fn example() -> Result<(), Error> {
128 /// let mut path = Path::from_str("authors.name")?;
129 ///
130 /// assert_eq!(path.pop(), Some("name".parse()?));
131 /// assert_eq!(path.pop(), Some("authors".parse()?));
132 /// assert_eq!(path.pop(), None);
133 /// #
134 /// # Ok(())
135 /// # }
136 /// #
137 /// # fn main() {
138 /// # example().unwrap();
139 /// # }
140 /// ```
141 pub fn pop(&mut self) -> Option<Key> {
142 self.0.pop()
143 }
144
145 /// Appends a `Key` to the back of a `Path`.
146 ///
147 /// # Example
148 ///
149 /// ```
150 /// # extern crate json_api;
151 /// #
152 /// # use json_api::Error;
153 /// # use json_api::value::Path;
154 /// #
155 /// # fn example() -> Result<(), Error> {
156 /// let mut path = Path::new();
157 ///
158 /// path.push("authors".parse()?);
159 /// path.push("name".parse()?);
160 ///
161 /// assert_eq!(path, "authors.name");
162 /// #
163 /// # Ok(())
164 /// # }
165 /// #
166 /// # fn main() {
167 /// # example().unwrap();
168 /// # }
169 /// ```
170 pub fn push(&mut self, key: Key) {
171 self.0.push(key);
172 }
173
174 /// Reserves capacity for at least `additional` more keys to be inserted.
175 /// Does nothing if the capacity is already sufficient.
176 ///
177 /// # Panics
178 ///
179 /// Panics if the new capacity overflows usize.
180 ///
181 /// # Example
182 ///
183 /// ```
184 /// # extern crate json_api;
185 /// #
186 /// # use json_api::value::Path;
187 /// #
188 /// # fn main() {
189 /// let mut path = Path::new();
190 ///
191 /// path.reserve(10);
192 /// assert!(path.capacity() >= 10);
193 /// # }
194 /// ```
195 pub fn reserve(&mut self, additional: usize) {
196 self.0.reserve(additional);
197 }
198
199 /// Reserves the minimum capacity for exactly `additional` more keys to be
200 /// inserted.
201 ///
202 /// Does nothing if the capacity is already sufficient.
203 ///
204 /// # Panics
205 ///
206 /// Panics if the new capacity overflows usize.
207 ///
208 /// # Example
209 ///
210 /// ```
211 /// # extern crate json_api;
212 /// #
213 /// # use json_api::value::Path;
214 /// #
215 /// # fn main() {
216 /// let mut path = Path::new();
217 ///
218 /// path.reserve_exact(10);
219 /// assert!(path.capacity() >= 10);
220 /// # }
221 /// ```
222 pub fn reserve_exact(&mut self, additional: usize) {
223 self.0.reserve_exact(additional);
224 }
225
226 /// Shrinks the capacity of the path as much as possible.
227 ///
228 /// # Example
229 ///
230 /// ```
231 /// # extern crate json_api;
232 /// #
233 /// # use json_api::Error;
234 /// # use json_api::value::Path;
235 /// #
236 /// # fn example() -> Result<(), Error> {
237 /// let mut path = Path::with_capacity(10);
238 ///
239 /// path.push("authors".parse()?);
240 /// path.push("name".parse()?);
241 ///
242 /// path.shrink_to_fit();
243 /// assert!(path.capacity() >= 2);
244 /// #
245 /// # Ok(())
246 /// # }
247 /// #
248 /// # fn main() {
249 /// # example().unwrap();
250 /// # }
251 /// ```
252 pub fn shrink_to_fit(&mut self) {
253 self.0.shrink_to_fit();
254 }
255}
256
257impl AsRef<[Key]> for Path {
258 fn as_ref(&self) -> &[Key] {
259 self
260 }
261}
262
263impl Borrow<[Key]> for Path {
264 fn borrow(&self) -> &[Key] {
265 self
266 }
267}
268
269impl Deref for Path {
270 type Target = [Key];
271
272 fn deref(&self) -> &Self::Target {
273 &self.0
274 }
275}
276
277impl Display for Path {
278 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
279 f.write_str(&self.stringify())
280 }
281}
282
283impl Extend<Key> for Path {
284 fn extend<I>(&mut self, iter: I)
285 where
286 I: IntoIterator<Item = Key>,
287 {
288 self.0.extend(iter);
289 }
290}
291
292impl<'a> Extend<&'a Key> for Path {
293 fn extend<I>(&mut self, iter: I)
294 where
295 I: IntoIterator<Item = &'a Key>,
296 {
297 self.extend(iter.into_iter().cloned());
298 }
299}
300
301impl From<Path> for String {
302 fn from(path: Path) -> Self {
303 path.stringify()
304 }
305}
306
307impl From<Path> for Vec<u8> {
308 fn from(path: Path) -> Self {
309 path.to_bytes()
310 }
311}
312
313impl FromIterator<Key> for Path {
314 fn from_iter<I>(iter: I) -> Self
315 where
316 I: IntoIterator<Item = Key>,
317 {
318 Path(Vec::from_iter(iter))
319 }
320}
321
322impl FromStr for Path {
323 type Err = Error;
324
325 fn from_str(value: &str) -> Result<Self, Self::Err> {
326 value.split('.').map(Key::from_str).collect()
327 }
328}
329
330impl IntoIterator for Path {
331 type Item = Key;
332 type IntoIter = <Vec<Key> as IntoIterator>::IntoIter;
333
334 fn into_iter(self) -> Self::IntoIter {
335 self.0.into_iter()
336 }
337}
338
339impl<'a> IntoIterator for &'a Path {
340 type Item = &'a Key;
341 type IntoIter = Iter<'a, Key>;
342
343 fn into_iter(self) -> Self::IntoIter {
344 self.iter()
345 }
346}
347
348impl PartialEq<str> for Path {
349 fn eq(&self, rhs: &str) -> bool {
350 let mut parts = rhs.split('.');
351
352 for part in self.iter().map(|key| Some(&**key)) {
353 if part != parts.next() {
354 return false;
355 }
356 }
357
358 parts.next().is_none()
359 }
360}
361
362impl<'a> PartialEq<&'a str> for Path {
363 fn eq(&self, rhs: &&str) -> bool {
364 self == *rhs
365 }
366}
367
368impl PartialEq<String> for Path {
369 fn eq(&self, rhs: &String) -> bool {
370 self == &*rhs
371 }
372}
373
374impl<'de> Deserialize<'de> for Path {
375 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
376 where
377 D: Deserializer<'de>,
378 {
379 use serde::de::{Error, Visitor};
380
381 struct PathVisitor;
382
383 impl<'de> Visitor<'de> for PathVisitor {
384 type Value = Path;
385
386 fn expecting(&self, f: &mut Formatter) -> fmt::Result {
387 f.write_str(r#"a string of json api member names, separated by a ".""#)
388 }
389
390 fn visit_str<E: Error>(self, value: &str) -> Result<Self::Value, E> {
391 value.parse().map_err(Error::custom)
392 }
393 }
394
395 deserializer.deserialize_str(PathVisitor)
396 }
397}
398
399impl Serialize for Path {
400 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
401 where
402 S: Serializer,
403 {
404 serializer.serialize_str(&self.stringify())
405 }
406}
407
408impl Sealed for Path {}
409
410impl Stringify for Path {
411 fn to_bytes(&self) -> Vec<u8> {
412 let mut bytes = match self.char_count() {
413 0 => return Default::default(),
414 len => Vec::with_capacity(len),
415 };
416
417 for key in self {
418 if !bytes.is_empty() {
419 bytes.push(b'.');
420 }
421
422 bytes.append(&mut key.to_bytes());
423 }
424
425 bytes
426 }
427}
428
429/// Shared behavior for types that can be combined to create a `Path`.
430pub trait Segment<T> {
431 /// Combines `self` with `other`. Returns a new `Path`.
432 ///
433 /// # Example
434 ///
435 /// ```
436 /// # extern crate json_api;
437 /// #
438 /// # use json_api::Error;
439 /// #
440 /// # fn example() -> Result<(), Error> {
441 /// use json_api::value::fields::{Key, Path, Segment};
442 ///
443 /// let posts = "posts".parse::<Key>()?;
444 /// let comments = "comments".parse::<Key>()?;
445 ///
446 /// let path: Path = posts.join(&comments);
447 /// assert_eq!(path, "posts.comments");
448 ///
449 /// let authors = "authors".parse::<Key>()?;
450 /// let name = "name".parse::<Key>()?;
451 ///
452 /// let path: Path = path.join(&authors.join(&name));
453 /// assert_eq!(path, "posts.comments.authors.name");
454 /// #
455 /// # Ok(())
456 /// # }
457 /// #
458 /// # fn main() {
459 /// # example().unwrap();
460 /// # }
461 /// ```
462 fn join(&self, other: T) -> Path;
463}
464
465impl Segment<Key> for Key {
466 fn join(&self, other: Key) -> Path {
467 let mut path = Path::with_capacity(2);
468
469 path.push(self.clone());
470 path.push(other);
471
472 path
473 }
474}
475
476impl<'a> Segment<&'a Key> for Key {
477 fn join(&self, other: &Key) -> Path {
478 self.join(other.clone())
479 }
480}
481
482impl<'a, T> Segment<T> for Key
483where
484 T: IntoIterator<Item = &'a Key>,
485{
486 fn join(&self, other: T) -> Path {
487 let iter = other.into_iter();
488 let mut path = match iter.size_hint() {
489 (_, Some(size)) => Path::with_capacity(size + 1),
490 _ => Path::new(),
491 };
492
493 path.push(self.clone());
494 path.extend(iter);
495
496 path
497 }
498}
499
500impl Segment<Key> for Path {
501 fn join(&self, other: Key) -> Path {
502 let mut path = Path::with_capacity(self.len() + 1);
503
504 path.extend(self);
505 path.push(other);
506
507 path
508 }
509}
510
511impl<'a> Segment<&'a Key> for Path {
512 fn join(&self, other: &Key) -> Path {
513 self.join(other.clone())
514 }
515}
516
517impl<'a, T> Segment<T> for Path
518where
519 T: IntoIterator<Item = &'a Key>,
520{
521 fn join(&self, other: T) -> Path {
522 let iter = other.into_iter();
523 let mut path = match iter.size_hint() {
524 (_, Some(size)) => Path::with_capacity(self.len() + size),
525 _ => Path::new(),
526 };
527
528 path.extend(self);
529 path.extend(iter);
530
531 path
532 }
533}