json_schema_tools/
path.rs

1use super::constants::{DEFS_KEY, PROPERTIES_KEY};
2use std::fmt::Display;
3
4#[derive(Clone, Copy, Debug, Eq, PartialEq)]
5pub enum Entry<'a> {
6    Key(&'a str),
7    Index(usize),
8}
9
10impl<'a> From<&'a str> for Entry<'a> {
11    fn from(value: &'a str) -> Self {
12        Self::Key(value)
13    }
14}
15
16impl<'a> From<usize> for Entry<'a> {
17    fn from(value: usize) -> Self {
18        Self::Index(value)
19    }
20}
21
22#[derive(Clone, Debug, Default, Eq, PartialEq)]
23pub struct Path<'a> {
24    entries: Vec<Entry<'a>>,
25}
26
27impl<'a> Path<'a> {
28    pub fn is_empty(&self) -> bool {
29        self.entries.is_empty()
30    }
31
32    pub fn len(&self) -> usize {
33        self.entries.len()
34    }
35
36    pub fn push<E>(&mut self, value: E)
37    where
38        Entry<'a>: From<E>,
39    {
40        self.entries.push(Entry::from(value));
41    }
42
43    /// This path points to a JSON object with arbitrary keys
44    pub fn allows_arbitrary_keys(&self) -> bool {
45        self.entries
46            .last()
47            .filter(|entry| matches!(entry, Entry::Key(PROPERTIES_KEY) | Entry::Key(DEFS_KEY)))
48            .is_some()
49    }
50}
51
52impl<'a> Display for Path<'a> {
53    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
54        for entry in &self.entries {
55            match entry {
56                Entry::Key(key) => {
57                    write!(f, ".{}", key)?;
58                }
59                Entry::Index(index) => {
60                    write!(f, "[{}]", index)?;
61                }
62            }
63        }
64
65        Ok(())
66    }
67}