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}