ephemeris_documents/json/
cst.rs1mod array;
9mod key;
10mod object;
11mod quote;
12mod scalar;
13mod tail;
14mod trivia;
15
16use std::fmt;
17
18pub(super) use self::array::{Array, Item};
19pub(super) use self::key::Key;
20pub(super) use self::object::{Member, Object};
21pub(super) use self::scalar::Scalar;
22pub(super) use self::tail::{Comma, Position, Tail};
23use self::trivia::Indent;
24pub(super) use self::trivia::Trivia;
25use super::Dialect;
26use super::parser::Parser;
27use crate::annotation::{Annotated, AnnotatedValue};
28use crate::backend::Editable;
29use crate::error::JsonError;
30use crate::header::Applied;
31
32#[derive(Debug, Clone)]
34pub(crate) struct Document {
35 dialect: Dialect,
36 pub(super) value: Value,
37 trailing: Trivia,
38 indent: Indent,
40}
41
42impl Document {
43 pub(super) fn parsed(dialect: Dialect, value: Value, trailing: Trivia) -> Self {
46 let indent = value
47 .as_object()
48 .and_then(Object::indent_unit)
49 .unwrap_or_default();
50 Self {
51 dialect,
52 value,
53 trailing,
54 indent,
55 }
56 }
57
58 pub(super) fn end_with_newline(&mut self) {
60 let text = [self.trailing.as_str().trim_end_matches('\n'), "\n"].concat();
61 self.trailing = Trivia::new(text);
62 }
63
64 pub(super) fn parse(source: &str, dialect: Dialect) -> Result<Self, JsonError> {
70 Parser::parse(source, dialect)
71 }
72
73 pub(super) fn build(tree: &Annotated, dialect: Dialect) -> Self {
75 let leading = Trivia::root(tree.comment.as_ref(), dialect);
76 Self {
77 dialect,
78 value: Value::build(tree, dialect, 0, leading),
79 trailing: Trivia::new("\n".to_owned()),
80 indent: Indent::default(),
81 }
82 }
83}
84
85impl Editable for Document {
86 type Node = Value;
87
88 fn header_text(&self) -> &str {
89 self.value.leading.as_str()
90 }
91
92 fn leading(&self) -> (&str, &str) {
93 ("", self.value.leading.as_str())
94 }
95
96 fn set_leading(&mut self, applied: Applied<'_>) {
97 self.value.leading = Trivia::new(applied.into_text());
98 }
99
100 fn root(&self) -> &Value {
101 &self.value
102 }
103
104 fn root_mut(&mut self) -> &mut Value {
106 if let Kind::Object(object) = &mut self.value.kind {
107 object.set_unit(&self.indent);
108 }
109 &mut self.value
110 }
111}
112
113impl fmt::Display for Document {
114 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115 self.value.write(f, self.dialect)?;
116 write!(f, "{}", self.trailing)
117 }
118}
119
120#[derive(Debug, Clone, PartialEq, Eq)]
126pub(crate) struct Value {
127 pub(super) leading: Trivia,
128 pub(super) kind: Kind,
129}
130
131#[derive(Debug, Clone, PartialEq, Eq)]
133pub(crate) enum Kind {
134 Object(Object),
135 Array(Array),
136 Scalar(Scalar),
137}
138
139impl Value {
140 pub(super) const fn new(leading: Trivia, kind: Kind) -> Self {
141 Self { leading, kind }
142 }
143
144 pub(super) const fn is_object(&self) -> bool {
145 matches!(self.kind, Kind::Object(_))
146 }
147
148 pub(super) const fn as_object(&self) -> Option<&Object> {
149 match &self.kind {
150 Kind::Object(object) => Some(object),
151 Kind::Array(_) | Kind::Scalar(_) => None,
152 }
153 }
154
155 pub(super) const fn as_object_mut(&mut self) -> Option<&mut Object> {
156 match &mut self.kind {
157 Kind::Object(object) => Some(object),
158 Kind::Array(_) | Kind::Scalar(_) => None,
159 }
160 }
161
162 fn build(node: &Annotated, dialect: Dialect, depth: usize, leading: Trivia) -> Self {
163 let kind = match &node.value {
164 AnnotatedValue::Scalar(leaf) => Kind::Scalar(Scalar::build(leaf, dialect)),
165 AnnotatedValue::Array(items) => Kind::Array(Array::build(items, dialect, depth)),
166 AnnotatedValue::Object(entries) => Kind::Object(Object::build(entries, dialect, depth)),
167 };
168 Self { leading, kind }
169 }
170
171 fn write(&self, f: &mut fmt::Formatter<'_>, dialect: Dialect) -> fmt::Result {
172 write!(f, "{}", self.leading)?;
173 self.kind.write(f, dialect)
174 }
175
176 fn trivia_mut(&mut self, visit: &mut dyn FnMut(&mut Trivia)) {
178 visit(&mut self.leading);
179 self.kind.trivia_mut(visit);
180 }
181
182 fn reindent_unit(&mut self, unit: &Indent) {
185 self.trivia_mut(&mut |trivia| trivia.reindent_unit(unit));
186 }
187}
188
189impl Kind {
190 fn write(&self, f: &mut fmt::Formatter<'_>, dialect: Dialect) -> fmt::Result {
191 match self {
192 Self::Object(object) => object.write(f, dialect),
193 Self::Array(array) => array.write(f, dialect),
194 Self::Scalar(scalar) => f.write_str(scalar.text()),
195 }
196 }
197
198 fn trivia_mut(&mut self, visit: &mut dyn FnMut(&mut Trivia)) {
199 match self {
200 Self::Object(object) => object.trivia_mut(visit),
201 Self::Array(array) => array.trivia_mut(visit),
202 Self::Scalar(_) => {}
203 }
204 }
205
206 fn reindent_from(&mut self, from: &str, to: &str) {
208 self.trivia_mut(&mut |trivia| trivia.reindent_from(from, to));
209 }
210}