jsonptr/
component.rs

1use crate::{Pointer, Token, Tokens};
2
3/// A single [`Token`] or the root of a JSON Pointer
4#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
5pub enum Component<'t> {
6    /// The document root
7    Root,
8    /// A segment of a JSON Pointer
9    Token(Token<'t>),
10}
11impl<'t> From<Token<'t>> for Component<'t> {
12    fn from(token: Token<'t>) -> Self {
13        Self::Token(token)
14    }
15}
16
17/// An iterator over the [`Component`]s of a JSON Pointer
18#[derive(Debug)]
19pub struct Components<'t> {
20    tokens: Tokens<'t>,
21    sent_root: bool,
22}
23
24impl<'t> Iterator for Components<'t> {
25    type Item = Component<'t>;
26    fn next(&mut self) -> Option<Self::Item> {
27        if !self.sent_root {
28            self.sent_root = true;
29            return Some(Component::Root);
30        }
31        self.tokens.next().map(Component::Token)
32    }
33}
34
35impl<'t> From<&'t Pointer> for Components<'t> {
36    fn from(pointer: &'t Pointer) -> Self {
37        Self {
38            sent_root: false,
39            tokens: pointer.tokens(),
40        }
41    }
42}
43
44#[cfg(test)]
45mod tests {
46    use super::*;
47
48    #[test]
49    fn components() {
50        let ptr = Pointer::from_static("");
51        let components: Vec<_> = Components::from(ptr).collect();
52        assert_eq!(components, vec![Component::Root]);
53
54        let ptr = Pointer::from_static("/foo");
55        let components = ptr.components().collect::<Vec<_>>();
56        assert_eq!(
57            components,
58            vec![Component::Root, Component::Token("foo".into())]
59        );
60
61        let ptr = Pointer::from_static("/foo/bar/-/0/baz");
62        let components = ptr.components().collect::<Vec<_>>();
63        assert_eq!(
64            components,
65            vec![
66                Component::Root,
67                Component::from(Token::from("foo")),
68                Component::Token("bar".into()),
69                Component::Token("-".into()),
70                Component::Token("0".into()),
71                Component::Token("baz".into())
72            ]
73        );
74    }
75}