jsona/dom/
node.rs

1use super::error::DomError;
2use super::keys::{KeyOrIndex, Keys};
3use super::query_keys::QueryKeys;
4use super::visitor::{VisitControl, Visitor};
5use crate::error::Error as JsonaError;
6use crate::parser;
7use crate::private::Sealed;
8use crate::syntax::SyntaxElement;
9use crate::util::mapper;
10use crate::util::shared::Shared;
11use crate::util::{check_quote, quote, unquote};
12
13use indexmap::IndexMap;
14use once_cell::unsync::OnceCell;
15use rowan::{NodeOrToken, TextRange};
16use serde_json::Number as JsonNumber;
17use std::str::FromStr;
18use std::string::String as StdString;
19use std::sync::Arc;
20
21pub trait DomNode: Sized + Sealed {
22    fn node_syntax(&self) -> Option<&SyntaxElement>;
23    fn syntax(&self) -> Option<&SyntaxElement>;
24    fn errors(&self) -> &Shared<Vec<DomError>>;
25    fn annotations(&self) -> Option<&Annotations>;
26}
27
28#[derive(Debug, Clone)]
29pub enum Node {
30    Null(Null),
31    Bool(Bool),
32    Number(Number),
33    String(String),
34    Array(Array),
35    Object(Object),
36}
37
38impl Sealed for Node {}
39
40impl_dom_node_for_node!(Null, Number, String, Bool, Array, Object,);
41
42impl Node {
43    pub fn path(&self, keys: &Keys) -> Option<Node> {
44        let mut node = self.clone();
45        for key in keys.iter() {
46            node = node.get(key)?;
47        }
48        Some(node)
49    }
50
51    pub fn get(&self, key: &KeyOrIndex) -> Option<Node> {
52        match key {
53            KeyOrIndex::Index(i) => self.as_array().and_then(|v| v.get(*i)),
54            KeyOrIndex::Key(k) => {
55                if k.is_property() {
56                    self.as_object().and_then(|v| v.get(k))
57                } else {
58                    self.annotations().and_then(|v| v.get(k))
59                }
60            }
61        }
62    }
63
64    pub fn validate(&self) -> Result<(), impl Iterator<Item = DomError> + core::fmt::Debug> {
65        let mut errors = Vec::new();
66        self.validate_all_impl(&mut errors);
67        if errors.is_empty() {
68            Ok(())
69        } else {
70            Err(errors.into_iter())
71        }
72    }
73
74    pub fn is_valid(&self) -> bool {
75        let mut valid = true;
76        self.is_valid_impl(&mut valid);
77        valid
78    }
79
80    pub fn is_scalar(&self) -> bool {
81        matches!(
82            self,
83            Node::Null(_) | Node::Bool(_) | Node::Number(_) | Node::String(_)
84        )
85    }
86
87    pub fn is_integer(&self) -> bool {
88        match self {
89            Self::Number(v) => v.is_integer(),
90            _ => false,
91        }
92    }
93
94    pub fn text_range(&self) -> Option<TextRange> {
95        self.syntax().map(|v| v.text_range())
96    }
97
98    pub fn node_text_range(&self) -> Option<TextRange> {
99        self.node_syntax().map(|v| v.text_range())
100    }
101
102    pub fn matches_all(
103        &self,
104        keys: QueryKeys,
105        match_children: bool,
106    ) -> Result<impl Iterator<Item = (Keys, Node)> + ExactSizeIterator, DomError> {
107        let all: Vec<(Keys, Node)> = Visitor::new(self, &(), |_, _, _| VisitControl::AddIter)
108            .into_iter()
109            .collect();
110        let mut output = vec![];
111        for (k, v) in all {
112            if keys.is_match(&k, match_children) {
113                output.push((k, v));
114            }
115        }
116        Ok(output.into_iter())
117    }
118
119    pub fn scalar_text(&self) -> Option<StdString> {
120        match self {
121            Node::Null(v) => {
122                if v.errors().read().is_empty() {
123                    Some("null".to_string())
124                } else {
125                    None
126                }
127            }
128            Node::Bool(v) => {
129                let text = match self.syntax() {
130                    Some(syntax) => syntax.to_string(),
131                    None => v.value().to_string(),
132                };
133                Some(text)
134            }
135            Node::Number(v) => {
136                let text = match self.syntax() {
137                    Some(syntax) => syntax.to_string(),
138                    None => v.value().to_string(),
139                };
140                Some(text)
141            }
142            Node::String(v) => {
143                let text = match self.syntax() {
144                    Some(syntax) => syntax.to_string(),
145                    None => quote(v.value(), true),
146                };
147                Some(text)
148            }
149            Node::Array(_) | Node::Object(_) => None,
150        }
151    }
152
153    pub fn mapper_range(&self, mapper: &mapper::Mapper) -> Option<mapper::Range> {
154        self.syntax()
155            .and_then(|syntax| mapper.range(syntax.text_range()))
156    }
157
158    fn is_valid_impl(&self, valid: &mut bool) {
159        match self {
160            Node::Object(v) => {
161                if !v.errors().read().as_ref().is_empty() {
162                    *valid = false;
163                    return;
164                }
165                let items = v.inner.properties.read();
166                for (k, entry) in items.as_ref().iter() {
167                    if !k.is_valid() {
168                        *valid = false;
169                        return;
170                    }
171                    entry.is_valid_impl(valid);
172                    if !*valid {
173                        return;
174                    }
175                }
176            }
177            Node::Array(v) => {
178                if !v.errors().read().as_ref().is_empty() {
179                    *valid = false;
180                    return;
181                }
182                let items = v.inner.items.read();
183                for item in &**items.as_ref() {
184                    item.is_valid_impl(valid);
185                    if !*valid {
186                        return;
187                    }
188                }
189            }
190            Node::Bool(v) => {
191                if !v.errors().read().as_ref().is_empty() {
192                    *valid = false;
193                    return;
194                }
195            }
196            Node::String(v) => {
197                if !v.errors().read().as_ref().is_empty() {
198                    *valid = false;
199                    return;
200                }
201            }
202            Node::Number(v) => {
203                if !v.errors().read().as_ref().is_empty() {
204                    *valid = false;
205                    return;
206                }
207            }
208            Node::Null(v) => {
209                if !v.errors().read().as_ref().is_empty() {
210                    *valid = false;
211                    return;
212                }
213            }
214        }
215        if let Some(v) = self.annotations() {
216            if !v.errors().read().as_ref().is_empty() {
217                *valid = false;
218                return;
219            }
220            let items = v.inner.map.read();
221            for (k, node) in items.as_ref().iter() {
222                if !k.errors().read().as_ref().is_empty() {
223                    *valid = false;
224                    return;
225                }
226                node.is_valid_impl(valid);
227                if !*valid {
228                    return;
229                }
230            }
231        }
232    }
233
234    fn validate_all_impl(&self, errors: &mut Vec<DomError>) {
235        match self {
236            Node::Object(v) => {
237                errors.extend(v.errors().read().as_ref().iter().cloned());
238
239                let items = v.inner.properties.read();
240                for (k, entry) in items.as_ref().iter() {
241                    errors.extend(k.errors().read().as_ref().iter().cloned());
242                    entry.validate_all_impl(errors);
243                }
244            }
245            Node::Array(v) => {
246                errors.extend(v.errors().read().as_ref().iter().cloned());
247                let items = v.inner.items.read();
248                for item in &**items.as_ref() {
249                    item.validate_all_impl(errors);
250                }
251            }
252            Node::Bool(v) => {
253                errors.extend(v.errors().read().as_ref().iter().cloned());
254            }
255            Node::String(v) => {
256                errors.extend(v.errors().read().as_ref().iter().cloned());
257            }
258            Node::Number(v) => {
259                errors.extend(v.errors().read().as_ref().iter().cloned());
260            }
261            Node::Null(v) => {
262                errors.extend(v.errors().read().as_ref().iter().cloned());
263            }
264        }
265        if let Some(v) = self.annotations() {
266            errors.extend(v.errors().read().as_ref().iter().cloned());
267            let items = v.inner.map.read();
268            for (k, node) in items.as_ref().iter() {
269                errors.extend(k.errors().read().as_ref().iter().cloned());
270                node.validate_all_impl(errors);
271            }
272        }
273    }
274}
275
276impl Node {
277    define_value_fns!(Null, Null, is_null, as_null, get_as_null);
278    define_value_fns!(Bool, Bool, is_bool, as_bool, get_as_bool);
279    define_value_fns!(Number, Number, is_number, as_number, get_as_number);
280    define_value_fns!(String, String, is_string, as_string, get_as_string);
281    define_value_fns!(Object, Object, is_object, as_object, get_as_object);
282    define_value_fns!(Array, Array, is_array, as_array, get_as_array);
283}
284
285value_from!(Null, Number, String, Bool, Array, Object,);
286
287impl FromStr for Node {
288    type Err = JsonaError;
289
290    fn from_str(s: &str) -> Result<Self, Self::Err> {
291        let parse = parser::parse(s);
292        if !parse.errors.is_empty() {
293            return Err(JsonaError::InvalidSyntax {
294                errors: parse.errors,
295            });
296        }
297        let root = parse.into_dom();
298        if let Err(errors) = root.validate() {
299            return Err(JsonaError::InvalidDom {
300                errors: errors.collect(),
301            });
302        }
303        Ok(root)
304    }
305}
306
307#[derive(Debug, Default)]
308pub(crate) struct NullInner {
309    pub(crate) errors: Shared<Vec<DomError>>,
310    pub(crate) syntax: Option<SyntaxElement>,
311    pub(crate) node_syntax: Option<SyntaxElement>,
312    pub(crate) annotations: Option<Annotations>,
313}
314
315wrap_node! {
316    #[derive(Debug, Clone)]
317    pub struct Null { inner: NullInner }
318}
319
320impl Null {
321    pub fn new(annotations: Option<Annotations>) -> Self {
322        NullInner {
323            errors: Default::default(),
324            syntax: None,
325            node_syntax: None,
326            annotations,
327        }
328        .into()
329    }
330
331    pub fn is_valid(&self) -> bool {
332        Node::Null(self.clone()).is_valid()
333    }
334}
335
336#[derive(Debug)]
337pub(crate) struct BoolInner {
338    pub(crate) errors: Shared<Vec<DomError>>,
339    pub(crate) syntax: Option<SyntaxElement>,
340    pub(crate) node_syntax: Option<SyntaxElement>,
341    pub(crate) annotations: Option<Annotations>,
342    pub(crate) value: OnceCell<bool>,
343}
344
345wrap_node! {
346    #[derive(Debug, Clone)]
347    pub struct Bool { inner: BoolInner }
348}
349
350impl Bool {
351    pub fn new(value: bool, annotations: Option<Annotations>) -> Self {
352        BoolInner {
353            errors: Default::default(),
354            syntax: None,
355            node_syntax: None,
356            annotations,
357            value: value.into(),
358        }
359        .into()
360    }
361    /// A boolean value.
362    pub fn value(&self) -> bool {
363        *self.inner.value.get_or_init(|| {
364            self.syntax()
365                .and_then(|s| s.as_token())
366                .and_then(|s| s.text().parse().ok())
367                .unwrap_or_default()
368        })
369    }
370}
371
372#[derive(Debug)]
373pub(crate) struct NumberInner {
374    pub(crate) errors: Shared<Vec<DomError>>,
375    pub(crate) syntax: Option<SyntaxElement>,
376    pub(crate) node_syntax: Option<SyntaxElement>,
377    pub(crate) annotations: Option<Annotations>,
378    pub(crate) repr: NumberRepr,
379    pub(crate) value: OnceCell<JsonNumber>,
380}
381
382wrap_node! {
383    #[derive(Debug, Clone)]
384    pub struct Number { inner: NumberInner }
385}
386
387impl Number {
388    pub fn new(value: JsonNumber, annotations: Option<Annotations>) -> Self {
389        NumberInner {
390            errors: Default::default(),
391            syntax: None,
392            node_syntax: None,
393            annotations,
394            repr: Default::default(),
395            value: value.into(),
396        }
397        .into()
398    }
399
400    /// An number value.
401    pub fn value(&self) -> &JsonNumber {
402        self.inner.value.get_or_init(|| {
403            self.inner
404                .syntax
405                .as_ref()
406                .map(|s| {
407                    let text = s.as_token().unwrap().text().replace('_', "");
408
409                    match self.inner.repr {
410                        NumberRepr::Float => {
411                            match text.parse::<f64>().ok().and_then(JsonNumber::from_f64) {
412                                Some(v) => v,
413                                None => {
414                                    self.inner.errors.update(|errors| {
415                                        errors.push(DomError::InvalidNumber { syntax: s.clone() })
416                                    });
417                                    JsonNumber::from_f64(0.0).unwrap()
418                                }
419                            }
420                        }
421                        NumberRepr::Dec => {
422                            if text.starts_with('-') {
423                                JsonNumber::from(text.parse::<i64>().unwrap_or_default())
424                            } else {
425                                JsonNumber::from(text.parse::<u64>().unwrap_or_default())
426                            }
427                        }
428                        NumberRepr::Bin => JsonNumber::from(
429                            u64::from_str_radix(text.trim_start_matches("0b"), 2)
430                                .unwrap_or_default(),
431                        ),
432                        NumberRepr::Oct => JsonNumber::from(
433                            u64::from_str_radix(text.trim_start_matches("0o"), 8)
434                                .unwrap_or_default(),
435                        ),
436                        NumberRepr::Hex => JsonNumber::from(
437                            u64::from_str_radix(text.trim_start_matches("0x"), 16)
438                                .unwrap_or_default(),
439                        ),
440                    }
441                })
442                .unwrap_or_else(|| JsonNumber::from(0))
443        })
444    }
445    pub fn is_integer(&self) -> bool {
446        self.inner.repr != NumberRepr::Float
447    }
448}
449
450#[derive(Debug, Copy, Clone, PartialEq, Eq)]
451pub enum NumberRepr {
452    Dec,
453    Bin,
454    Oct,
455    Hex,
456    Float,
457}
458
459impl Default for NumberRepr {
460    fn default() -> Self {
461        Self::Float
462    }
463}
464
465#[derive(Debug)]
466pub(crate) struct StringInner {
467    pub(crate) errors: Shared<Vec<DomError>>,
468    pub(crate) syntax: Option<SyntaxElement>,
469    pub(crate) node_syntax: Option<SyntaxElement>,
470    pub(crate) annotations: Option<Annotations>,
471    pub(crate) value: OnceCell<StdString>,
472}
473
474wrap_node! {
475    #[derive(Debug, Clone)]
476    pub struct String { inner: StringInner }
477}
478
479impl String {
480    pub fn new(value: StdString, annotations: Option<Annotations>) -> Self {
481        StringInner {
482            errors: Default::default(),
483            syntax: None,
484            node_syntax: None,
485            annotations,
486            value: value.into(),
487        }
488        .into()
489    }
490
491    /// An unescaped value of the string.
492    pub fn value(&self) -> &str {
493        self.inner.value.get_or_init(|| {
494            self.inner
495                .syntax
496                .as_ref()
497                .map(|s| match unquote(&s.to_string()) {
498                    Ok(s) => s,
499                    Err(_) => {
500                        self.inner.errors.update(|errors| {
501                            errors.push(DomError::InvalidString { syntax: s.clone() })
502                        });
503                        StdString::new()
504                    }
505                })
506                .unwrap_or_default()
507        })
508    }
509}
510
511#[derive(Debug, Copy, Clone)]
512pub enum StringRepr {
513    Double,
514    Single,
515    Backtick,
516}
517
518impl Default for StringRepr {
519    fn default() -> Self {
520        Self::Double
521    }
522}
523
524#[derive(Debug)]
525pub(crate) struct ArrayInner {
526    pub(crate) errors: Shared<Vec<DomError>>,
527    pub(crate) syntax: Option<SyntaxElement>,
528    pub(crate) node_syntax: Option<SyntaxElement>,
529    pub(crate) annotations: Option<Annotations>,
530    pub(crate) items: Shared<Vec<Node>>,
531}
532
533wrap_node! {
534    #[derive(Debug, Clone)]
535    pub struct Array { inner: ArrayInner }
536}
537
538impl Array {
539    pub fn new(items: Vec<Node>, annotations: Option<Annotations>) -> Self {
540        ArrayInner {
541            errors: Default::default(),
542            syntax: None,
543            node_syntax: None,
544            annotations,
545            items: items.into(),
546        }
547        .into()
548    }
549
550    pub fn get(&self, idx: usize) -> Option<Node> {
551        let items = self.inner.items.read();
552        items.get(idx).cloned()
553    }
554
555    pub fn value(&self) -> &Shared<Vec<Node>> {
556        &self.inner.items
557    }
558}
559
560#[derive(Debug)]
561pub(crate) struct ObjectInner {
562    pub(crate) errors: Shared<Vec<DomError>>,
563    pub(crate) syntax: Option<SyntaxElement>,
564    pub(crate) node_syntax: Option<SyntaxElement>,
565    pub(crate) annotations: Option<Annotations>,
566    pub(crate) properties: Shared<Map>,
567}
568
569wrap_node! {
570    #[derive(Debug, Clone)]
571    pub struct Object { inner: ObjectInner }
572}
573
574impl Object {
575    pub fn new(properties: Map, annotations: Option<Annotations>) -> Self {
576        ObjectInner {
577            errors: Default::default(),
578            syntax: None,
579            node_syntax: None,
580            annotations,
581            properties: properties.into(),
582        }
583        .into()
584    }
585
586    pub fn get(&self, key: &Key) -> Option<Node> {
587        let props = self.inner.properties.read();
588        props.value.get(key).map(|(node, _)| node.clone())
589    }
590
591    pub fn value(&self) -> &Shared<Map> {
592        &self.inner.properties
593    }
594}
595
596#[derive(Debug)]
597pub(crate) struct KeyInner {
598    pub(crate) errors: Shared<Vec<DomError>>,
599    pub(crate) syntax: Option<SyntaxElement>,
600    pub(crate) value: OnceCell<StdString>,
601    pub(crate) kind: KeyKind,
602}
603
604#[derive(Debug, Clone, Copy, PartialEq, Eq)]
605pub enum KeyKind {
606    Property,
607    Annotation,
608}
609
610#[derive(Debug, Clone)]
611pub struct Key {
612    inner: Arc<KeyInner>,
613}
614
615impl From<KeyInner> for Key {
616    fn from(inner: KeyInner) -> Self {
617        Self {
618            inner: Arc::new(inner),
619        }
620    }
621}
622
623impl From<&str> for Key {
624    fn from(v: &str) -> Self {
625        if v.starts_with('@') {
626            Self::annotation(v)
627        } else {
628            Self::property(v)
629        }
630    }
631}
632
633impl Key {
634    pub fn syntax(&self) -> Option<&SyntaxElement> {
635        self.inner.syntax.as_ref()
636    }
637
638    pub fn errors(&self) -> &Shared<Vec<DomError>> {
639        &self.inner.errors
640    }
641
642    pub fn property<T: Into<StdString>>(key: T) -> Self {
643        KeyInner {
644            errors: Default::default(),
645            syntax: None,
646            value: OnceCell::from(key.into()),
647            kind: KeyKind::Property,
648        }
649        .into()
650    }
651
652    pub fn annotation<T: Into<StdString>>(key: T) -> Self {
653        KeyInner {
654            errors: Default::default(),
655            syntax: None,
656            value: OnceCell::from(key.into()),
657            kind: KeyKind::Annotation,
658        }
659        .into()
660    }
661
662    /// An unescaped value of the key.
663    pub fn value(&self) -> &str {
664        self.inner.value.get_or_init(|| {
665            self.inner
666                .syntax
667                .as_ref()
668                .and_then(NodeOrToken::as_token)
669                .map(|s| {
670                    if self.is_annotation() {
671                        return s.to_string();
672                    }
673                    match unquote(s.text()) {
674                        Ok(s) => s,
675                        Err(_) => {
676                            self.inner.errors.update(|errors| {
677                                errors.push(DomError::InvalidString {
678                                    syntax: s.clone().into(),
679                                })
680                            });
681                            StdString::new()
682                        }
683                    }
684                })
685                .unwrap_or_default()
686        })
687    }
688
689    pub fn is_property(&self) -> bool {
690        self.inner.kind == KeyKind::Property
691    }
692
693    pub fn is_annotation(&self) -> bool {
694        self.inner.kind == KeyKind::Annotation
695    }
696
697    pub fn text_range(&self) -> Option<TextRange> {
698        self.syntax().map(|v| v.text_range())
699    }
700
701    pub fn annotation_name(&self) -> Option<StdString> {
702        if self.is_annotation() {
703            Some(self.value()[1..].to_string())
704        } else {
705            None
706        }
707    }
708
709    pub fn to_origin_string(&self) -> StdString {
710        match self.syntax() {
711            Some(v) => v.to_string(),
712            None => self.value().to_string(),
713        }
714    }
715
716    pub fn is_valid(&self) -> bool {
717        self.errors().read().is_empty()
718    }
719
720    pub fn is_quote(&self) -> bool {
721        check_quote(self.value()).is_some()
722    }
723
724    pub fn mapper_range(&self, mapper: &mapper::Mapper) -> Option<mapper::Range> {
725        self.syntax()
726            .and_then(|syntax| mapper.range(syntax.text_range()))
727    }
728}
729
730impl AsRef<str> for Key {
731    fn as_ref(&self) -> &str {
732        self.value()
733    }
734}
735
736impl core::fmt::Display for Key {
737    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
738        if self.is_annotation() {
739            self.value().fmt(f)
740        } else {
741            quote(self.value(), false).fmt(f)
742        }
743    }
744}
745
746impl PartialEq for Key {
747    fn eq(&self, other: &Self) -> bool {
748        if self.is_valid() && self.is_valid() {
749            return self.value().eq(other.value());
750        }
751        false
752    }
753}
754
755impl Eq for Key {}
756
757impl std::hash::Hash for Key {
758    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
759        if self.is_valid() {
760            return self.value().hash(state);
761        }
762        0.hash(state);
763    }
764}
765
766#[derive(Debug, Clone, Default)]
767pub struct Map {
768    pub(crate) value: IndexMap<Key, (Node, Option<SyntaxElement>)>,
769}
770
771impl Map {
772    pub fn len(&self) -> usize {
773        self.value.len()
774    }
775
776    pub fn syntax(&self, key: &Key) -> Option<SyntaxElement> {
777        self.value.get(key).and_then(|(_, syntax)| syntax.clone())
778    }
779
780    pub fn is_empty(&self) -> bool {
781        self.value.is_empty()
782    }
783
784    pub fn iter(&self) -> impl Iterator<Item = (&Key, &Node)> {
785        self.value.iter().map(|(key, (node, _))| (key, node))
786    }
787
788    pub fn add(&mut self, key: Key, node: Node, syntax: Option<SyntaxElement>) {
789        self.value.insert(key, (node, syntax));
790    }
791}
792
793#[derive(Debug)]
794pub(crate) struct AnnotationsInner {
795    pub(crate) errors: Shared<Vec<DomError>>,
796    pub(crate) map: Shared<Map>,
797}
798
799#[derive(Debug, Clone)]
800pub struct Annotations {
801    inner: Arc<AnnotationsInner>,
802}
803
804impl Annotations {
805    pub fn new(map: Map) -> Self {
806        AnnotationsInner {
807            errors: Default::default(),
808            map: map.into(),
809        }
810        .into()
811    }
812
813    pub fn errors(&self) -> &Shared<Vec<DomError>> {
814        &self.inner.errors
815    }
816
817    pub fn get(&self, key: &Key) -> Option<Node> {
818        let map = self.inner.map.read();
819        map.value.get(key).map(|(node, _)| node.clone())
820    }
821
822    pub fn annotation_syntax(&self, key: &Key) -> Option<SyntaxElement> {
823        let map = self.inner.map.read();
824        map.value.get(key).and_then(|(_, syntax)| syntax.clone())
825    }
826
827    pub fn value(&self) -> &Shared<Map> {
828        &self.inner.map
829    }
830
831    pub fn map_keys(&self) -> Vec<StdString> {
832        self.value()
833            .read()
834            .iter()
835            .map(|(k, _)| k.to_string())
836            .collect()
837    }
838}
839
840impl From<AnnotationsInner> for Annotations {
841    fn from(inner: AnnotationsInner) -> Self {
842        Self {
843            inner: Arc::new(inner),
844        }
845    }
846}