1use core::slice;
2use std::fmt;
3
4use crate::binary::{
5 BArray, BKeyValue, BMap, BReference, Binary, TYPE_ARRAY, TYPE_KEYVAL, TYPE_MAP,
6};
7use crate::error::DaptResult;
8use crate::{Error, Path};
9
10use super::parser::Node;
11
12pub trait Aquireable {
16 fn aquire(&self, bin: &mut Binary, b: BReference) -> DaptResult<BKeyValue>;
17}
18
19pub trait Discoverable {
22 fn find<F>(&self, bin: &Binary, b: BReference, f: &mut F)
23 where
24 F: FnMut(BReference);
25}
26
27#[derive(Debug, PartialEq, Clone)]
28pub struct FieldLiteral {
29 name: String,
30}
31
32impl FieldLiteral {
40 pub fn new(name: &str) -> FieldLiteral {
41 FieldLiteral {
42 name: name.to_string(),
43 }
44 }
45
46 pub fn from_escaped(name: &str) -> FieldLiteral {
47 let mut c = name.chars().peekable();
51 let mut name = String::with_capacity(name.len());
52
53 while let Some(character) = c.next() {
54 match character {
55 '\\' => {
56 if let Some(next) = c.next() {
59 name.push(next);
60 }
61 }
62 '"' => (),
65 _ => name.push(character),
66 }
67 }
68
69 FieldLiteral { name }
70 }
71}
72
73impl Discoverable for FieldLiteral {
74 fn find<F>(&self, bin: &Binary, b: BReference, f: &mut F)
77 where
78 F: FnMut(BReference),
79 {
80 let n = match b.val_at(bin) {
81 Some(n) => n,
82 None => return,
83 };
84
85 match n.get_type(bin) {
86 TYPE_MAP => {
87 let bcoll = BMap::from(n);
88 if let Some(child_location) = bcoll.child_key(&self.name, bin) {
89 f(child_location);
90 }
91 }
92 _ => (),
93 };
94 }
95}
96
97impl Aquireable for FieldLiteral {
98 fn aquire(&self, bin: &mut Binary, b: BReference) -> DaptResult<BKeyValue> {
99 let mut reg = None;
100 self.find(bin, b, &mut |x| reg = Some(x));
101
102 if reg.is_some() {
103 return Ok(reg
104 .unwrap()
105 .key_at(bin)
106 .ok_or_else(|| Error::CanNotAquire(format!("could not aquire {}", self)))?);
107 }
108
109 match b.token_at(bin) {
110 None => {
113 let (key_bref, bkv) = BKeyValue::new(None, BReference::from(0), &self.name, bin);
114 let (map_bref, _) = BMap::new(Some(b), slice::from_ref(&key_bref), bin);
116 b.set_index(bin, *map_bref);
118 Ok(bkv)
119 }
120 Some(tok) if tok.get_type(bin) == TYPE_MAP => {
122 let (key_bref, bkv) = BKeyValue::new(
123 Some(tok.get_reference(bin)),
124 BReference::from(0),
125 &self.name,
126 bin,
127 );
128
129 let bcoll = BMap::from(tok);
131 bcoll.add_child(key_bref, bin);
132
133 Ok(bkv)
135 }
136 Some(tok) if tok.get_type(bin) == TYPE_KEYVAL => {
139 let orig_bkv = BKeyValue::from(tok);
140 let child = orig_bkv.child(bin);
141
142 if child.is_some() {
144 return self.aquire(bin, child.unwrap());
145 }
146
147 let (key_bref, bkv) = BKeyValue::new(None, BReference::from(0), &self.name, bin);
148 let (map_bref, _) = BMap::new(Some(b), slice::from_ref(&key_bref), bin);
150 orig_bkv.set_child(map_bref, bin);
152 Ok(bkv)
153 }
154 Some(_) => Err("Cannot add a field to a non map type".into()),
156 }
157 }
158}
159
160impl fmt::Display for FieldLiteral {
161 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
162 if self.name.contains('.') || self.name.contains('"') || self.name.contains(' ') {
166 write!(f, "\"")?;
167 let c = self.name.chars();
168 for character in c {
169 match character {
170 '"' => {
171 write!(f, "\\\"")?;
172 }
173 _ => write!(f, "{}", character)?,
174 }
175 }
176 write!(f, "\"")
177 } else {
178 write!(f, "{}", self.name)
179 }
180 }
181}
182
183#[derive(Debug, PartialEq, Clone)]
189pub struct Array {
190 index: Option<usize>,
191}
192
193impl Array {
194 pub fn new(index: Option<usize>) -> Array {
195 Array { index }
196 }
197}
198
199impl Discoverable for Array {
200 fn find<F>(&self, bin: &Binary, b: BReference, f: &mut F)
203 where
204 F: FnMut(BReference),
205 {
206 let n = match b.val_at(bin) {
207 Some(n) => n,
208 None => return,
209 };
210
211 match n.get_type(bin) {
212 TYPE_ARRAY => {
213 let bcoll = BArray::from(n);
214 if let None = self.index {
215 for i in 0..bcoll.length(bin) {
216 f(bcoll.child_index(bin, i).unwrap());
219 }
220 } else {
221 if let Some(child_location) = bcoll.child_index(bin, self.index.unwrap()) {
222 f(child_location);
223 }
224 }
225 }
226 _ => (),
227 };
228 }
229}
230
231impl fmt::Display for Array {
232 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
233 match self.index {
234 Some(i) => write!(f, "[{}]", i),
235 None => write!(f, "[]"),
236 }
237 }
238}
239
240#[derive(Debug, PartialEq, Clone)]
243pub struct Wildcard;
244
245impl Discoverable for Wildcard {
246 fn find<F>(&self, bin: &Binary, b: BReference, f: &mut F)
249 where
250 F: FnMut(BReference),
251 {
252 let n = match b.val_at(bin) {
253 Some(n) => n,
254 None => return,
255 };
256
257 match n.get_type(bin) {
258 TYPE_MAP => {
259 let bcoll = BMap::from(n);
260 for i in 0..bcoll.length(bin) {
261 f(bcoll.child_index(bin, i).unwrap());
264 }
265 }
266 _ => (),
267 };
268 }
269}
270
271impl fmt::Display for Wildcard {
272 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
273 write!(f, "*")
274 }
275}
276
277#[derive(Debug, PartialEq, Clone)]
281pub struct Recursive {
282 child: Box<Node>,
283}
284
285impl Recursive {
286 pub fn new(child: Node) -> Recursive {
287 Recursive {
288 child: Box::new(child),
289 }
290 }
291}
292
293impl Discoverable for Recursive {
294 fn find<F>(&self, bin: &Binary, b: BReference, f: &mut F)
297 where
298 F: FnMut(BReference),
299 {
300 b.walk(bin, &mut |childref| {
301 self.child.find(bin, childref, f);
302 true
303 });
304 }
305}
306
307impl fmt::Display for Recursive {
308 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
309 write!(f, "~.{}", self.child)
310 }
311}
312
313#[derive(Debug, PartialEq, Clone)]
318pub struct First {
319 paths: Vec<Path>,
320}
321
322impl First {
323 pub fn new(paths: Vec<Path>) -> First {
324 First { paths }
325 }
326}
327
328impl Discoverable for First {
329 fn find<F>(&self, bin: &Binary, b: BReference, f: &mut F)
332 where
333 F: FnMut(BReference),
334 {
335 for path in &self.paths {
336 let ptrs = path.find_simple(bin, b);
337 match ptrs.get(0) {
338 Some(p) => {
339 f(*p);
340 return;
341 }
342 None => (),
343 }
344 }
345 }
346}
347
348impl fmt::Display for First {
349 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
350 write!(f, "{{")?;
351
352 for (x, path) in self.paths.iter().enumerate() {
353 if x > 0 {
354 write!(f, ",")?;
355 }
356 write!(f, "{}", path)?;
357 }
358
359 write!(f, "}}")?;
360 Ok(())
361 }
362}
363
364#[derive(Debug, PartialEq, Clone)]
369pub struct Multi {
370 paths: Vec<Path>,
371}
372
373impl Multi {
374 pub fn new(paths: Vec<Path>) -> Multi {
375 Multi { paths }
376 }
377}
378
379impl Discoverable for Multi {
380 fn find<F>(&self, bin: &Binary, b: BReference, f: &mut F)
383 where
384 F: FnMut(BReference),
385 {
386 for path in &self.paths {
387 path.find_simple(bin, b).iter().for_each(|p| f(*p));
388 }
389 }
390}
391
392impl fmt::Display for Multi {
393 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
394 write!(f, "(")?;
395
396 for (x, path) in self.paths.iter().enumerate() {
397 if x > 0 {
398 write!(f, "|")?;
399 }
400 write!(f, "{}", path)?;
401 }
402
403 write!(f, ")")?;
404 Ok(())
405 }
406}
407
408#[derive(Debug, Clone)]
409pub struct Regexp {
410 name: regex::Regex,
411}
412
413impl Regexp {
414 pub fn new(name: &str) -> Regexp {
415 Regexp {
419 name: regex::Regex::new(name).unwrap(),
420 }
421 }
422}
423
424impl PartialEq for Regexp {
425 fn eq(&self, other: &Self) -> bool {
426 self.name.as_str() == other.name.as_str()
427 }
428}
429
430impl Discoverable for Regexp {
431 fn find<F>(&self, bin: &Binary, b: BReference, f: &mut F)
434 where
435 F: FnMut(BReference),
436 {
437 let n = match b.val_at(bin) {
438 Some(n) => n,
439 None => return,
440 };
441
442 match n.get_type(bin) {
443 TYPE_MAP => {
444 let bcoll = BMap::from(n);
445 for i in 0..bcoll.length(bin) {
446 let child = bcoll.child_index(bin, i).unwrap();
449 if self.name.is_match(child.key_at(bin).unwrap().key(bin)) {
450 f(child);
451 }
452 }
453 }
454 _ => (),
455 };
456 }
457}
458
459impl fmt::Display for Regexp {
460 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
461 write!(f, "/{}/", self.name)
465 }
466}