jsona/dom/
keys.rs

1use crate::parser::Parser;
2use crate::util::mapper;
3
4use super::from_syntax::keys_from_syntax;
5use super::node::Key;
6use super::Node;
7
8use rowan::TextRange;
9use std::iter::{empty, once};
10use std::str::FromStr;
11use std::sync::Arc;
12
13#[derive(Debug, Clone, PartialEq, Eq)]
14pub enum KeyOrIndex {
15    Index(usize),
16    Key(Key),
17}
18
19impl From<usize> for KeyOrIndex {
20    fn from(v: usize) -> Self {
21        Self::Index(v)
22    }
23}
24
25impl From<Key> for KeyOrIndex {
26    fn from(k: Key) -> Self {
27        Self::Key(k)
28    }
29}
30
31impl core::fmt::Display for KeyOrIndex {
32    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
33        match self {
34            KeyOrIndex::Index(v) => write!(f, "[{}]", v),
35            KeyOrIndex::Key(v) => {
36                if v.is_property() {
37                    write!(f, ".{}", v)
38                } else {
39                    write!(f, "{}", v)
40                }
41            }
42        }
43    }
44}
45
46impl KeyOrIndex {
47    pub fn property<T: Into<String>>(key: T) -> Self {
48        Self::Key(Key::property(key))
49    }
50
51    pub fn annotation<T: Into<String>>(key: T) -> Self {
52        Self::Key(Key::annotation(key))
53    }
54
55    pub fn is_index(&self) -> bool {
56        matches!(self, KeyOrIndex::Index(_))
57    }
58
59    pub fn is_key(&self) -> bool {
60        matches!(self, KeyOrIndex::Key(_))
61    }
62
63    pub fn is_property_key(&self) -> bool {
64        if let KeyOrIndex::Key(v) = self {
65            if v.is_property() {
66                return true;
67            }
68        }
69        false
70    }
71
72    pub fn is_annotation_key(&self) -> bool {
73        if let KeyOrIndex::Key(v) = self {
74            if v.is_annotation() {
75                return true;
76            }
77        }
78        false
79    }
80
81    pub fn as_index(&self) -> Option<&usize> {
82        if let KeyOrIndex::Index(v) = self {
83            Some(v)
84        } else {
85            None
86        }
87    }
88
89    pub fn as_key(&self) -> Option<&Key> {
90        if let KeyOrIndex::Key(v) = self {
91            Some(v)
92        } else {
93            None
94        }
95    }
96
97    pub fn as_property_key(&self) -> Option<&Key> {
98        if let KeyOrIndex::Key(v) = self {
99            if v.is_property() {
100                return Some(v);
101            }
102        }
103        None
104    }
105
106    pub fn as_annotation_key(&self) -> Option<&Key> {
107        if let KeyOrIndex::Key(v) = self {
108            if v.is_annotation() {
109                return Some(v);
110            }
111        }
112        None
113    }
114}
115
116#[derive(Debug, Clone)]
117pub struct Keys {
118    dotted: Arc<str>,
119    keys: Arc<[KeyOrIndex]>,
120}
121
122impl Keys {
123    pub fn new(keys: impl Iterator<Item = KeyOrIndex>) -> Self {
124        let keys: Arc<[KeyOrIndex]> = keys.collect();
125        let mut dotted = String::new();
126        for k in keys.iter() {
127            dotted.push_str(&k.to_string());
128        }
129        let dotted: Arc<str> = Arc::from(dotted);
130        Self { keys, dotted }
131    }
132
133    pub fn single(key: impl Into<KeyOrIndex>) -> Self {
134        Self::new(once(key.into()))
135    }
136
137    pub fn join(&self, key: impl Into<KeyOrIndex>) -> Self {
138        self.extend(once(key.into()))
139    }
140
141    pub fn extend<I, K>(&self, keys: I) -> Self
142    where
143        I: IntoIterator<Item = K>,
144        K: Into<KeyOrIndex>,
145    {
146        Self::new(
147            self.keys
148                .iter()
149                .cloned()
150                .chain(keys.into_iter().map(Into::into)),
151        )
152    }
153
154    pub fn first(&self) -> Option<&KeyOrIndex> {
155        self.keys.first()
156    }
157
158    pub fn last(&self) -> Option<&KeyOrIndex> {
159        self.keys.last()
160    }
161
162    pub fn last_property_key(&self) -> Option<&Key> {
163        self.last().and_then(|v| v.as_property_key())
164    }
165
166    pub fn last_annotation_key(&self) -> Option<&Key> {
167        self.last().and_then(|v| v.as_annotation_key())
168    }
169
170    pub fn last_text_range(&self) -> Option<TextRange> {
171        match self.last() {
172            Some(KeyOrIndex::Key(k)) => k.syntax().map(|v| v.text_range()),
173            _ => None,
174        }
175    }
176
177    pub fn iter(&self) -> impl ExactSizeIterator<Item = &KeyOrIndex> + DoubleEndedIterator {
178        self.keys.iter()
179    }
180
181    pub fn iter_keys(&self) -> Vec<Keys> {
182        (0..self.keys.len() + 1)
183            .into_iter()
184            .map(|v| Keys::new(self.keys.iter().take(v).cloned()))
185            .collect()
186    }
187
188    pub fn dotted(&self) -> &str {
189        &*self.dotted
190    }
191
192    pub fn len(&self) -> usize {
193        self.keys.len()
194    }
195
196    pub fn is_empty(&self) -> bool {
197        self.keys.len() == 0
198    }
199
200    pub fn parent(&self) -> Option<Keys> {
201        if self.len() < 2 {
202            return None;
203        }
204        Some(Keys::new(self.iter().take(self.len() - 1).cloned()))
205    }
206
207    pub fn shift(&self) -> Option<(KeyOrIndex, Self)> {
208        if self.is_empty() {
209            return None;
210        }
211        let (left, right) = self.keys.split_at(1);
212        Some((
213            left.get(0).cloned().unwrap(),
214            Self::new(right.iter().cloned()),
215        ))
216    }
217
218    pub fn shift_annotation(&self) -> (Option<Key>, Self) {
219        match self.keys.iter().enumerate().find(|(_, k)| {
220            if let KeyOrIndex::Key(k) = k {
221                k.is_annotation()
222            } else {
223                false
224            }
225        }) {
226            Some((i, k)) => (
227                Some(k.as_annotation_key().cloned().unwrap()),
228                Self::new(self.keys.iter().skip(i + 1).cloned()),
229            ),
230            None => (None, self.clone()),
231        }
232    }
233
234    pub fn mapper_range(&self, node: &Node, mapper: &mapper::Mapper) -> Option<mapper::Range> {
235        let key = self.last().and_then(|v| v.as_key())?;
236        let key_range = key.mapper_range(mapper)?;
237        match node.path(self).and_then(|v| v.mapper_range(mapper)) {
238            Some(value_range) => Some(key_range.join(&value_range)),
239            None => Some(key_range),
240        }
241    }
242}
243
244impl Default for Keys {
245    fn default() -> Self {
246        Self::new(empty())
247    }
248}
249
250impl IntoIterator for Keys {
251    type Item = KeyOrIndex;
252
253    type IntoIter = std::vec::IntoIter<KeyOrIndex>;
254
255    fn into_iter(self) -> Self::IntoIter {
256        Vec::from(&*self.keys).into_iter()
257    }
258}
259
260impl core::fmt::Display for Keys {
261    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
262        self.dotted.fmt(f)
263    }
264}
265
266impl FromStr for Keys {
267    type Err = Vec<crate::parser::Error>;
268
269    fn from_str(s: &str) -> Result<Self, Self::Err> {
270        let p = Parser::new(s).parse_keys_only(true);
271        if !p.errors.is_empty() {
272            return Err(p.errors);
273        }
274        Ok(Keys::new(keys_from_syntax(&p.into_syntax().into())))
275    }
276}
277
278impl PartialEq for Keys {
279    fn eq(&self, other: &Self) -> bool {
280        self.dotted == other.dotted
281    }
282}
283
284impl Eq for Keys {}
285
286impl std::hash::Hash for Keys {
287    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
288        self.dotted.hash(state);
289    }
290}