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}