Skip to main content

ephemeris_documents/json/cst/
array.rs

1//! Arrays of the JSON syntax tree.
2
3use std::fmt::{self, Write as _};
4
5use super::Value;
6use super::tail::{Position, Tail};
7use super::trivia::Trivia;
8use crate::annotation::Annotated;
9use crate::json::Dialect;
10
11/// An array. Its items are only reachable as a whole.
12#[derive(Debug, Clone, PartialEq, Eq)]
13pub(crate) struct Array {
14    items: Vec<Item>,
15    /// Trivia before the closing bracket.
16    inner: Trivia,
17}
18
19/// One array element and the trivia around it. The leading trivia is the
20/// value's.
21#[derive(Debug, Clone, PartialEq, Eq)]
22pub(crate) struct Item {
23    value: Value,
24    tail: Tail,
25}
26
27impl Item {
28    pub(in crate::json) const fn parsed(value: Value, tail: Tail) -> Self {
29        Self { value, tail }
30    }
31
32    fn build(node: &Annotated, dialect: Dialect, depth: usize) -> Self {
33        let leading = Trivia::above(node.comment.as_ref(), depth, dialect);
34        Self::parsed(
35            Value::build(node, dialect, depth, leading),
36            Tail::canonical(),
37        )
38    }
39}
40
41impl Array {
42    pub(in crate::json) const fn parsed(items: Vec<Item>, inner: Trivia) -> Self {
43        Self { items, inner }
44    }
45
46    pub(super) fn build(nodes: &[Annotated], dialect: Dialect, depth: usize) -> Self {
47        let child = depth.saturating_add(1);
48        let inner = if nodes.is_empty() {
49            Trivia::default()
50        } else {
51            Trivia::closing(depth)
52        };
53        Self::parsed(
54            nodes
55                .iter()
56                .map(|node| Item::build(node, dialect, child))
57                .collect(),
58            inner,
59        )
60    }
61
62    pub(super) fn trivia_mut(&mut self, visit: &mut dyn FnMut(&mut Trivia)) {
63        for item in &mut self.items {
64            item.value.trivia_mut(visit);
65            item.tail.trivia_mut(visit);
66        }
67        visit(&mut self.inner);
68    }
69
70    pub(super) fn write(&self, f: &mut fmt::Formatter<'_>, dialect: Dialect) -> fmt::Result {
71        f.write_char('[')?;
72        for (position, item) in Position::each(&self.items) {
73            item.value.write(f, dialect)?;
74            item.tail.write(f, dialect, position)?;
75        }
76        write!(f, "{}]", self.inner)
77    }
78}