1use std::borrow::Cow;
5use std::cell::Cell;
6use std::collections::HashSet;
7use std::convert::Infallible;
8use std::fmt;
9use std::num::FpCategory;
10use std::ops::{Index, IndexMut};
11
12use crate::stream::{Error, Event, Parser};
13use crate::{cow_static, IdentDisplay};
14
15fn maybe_debug<T: fmt::Debug>(value: Option<&T>) -> &dyn fmt::Debug {
16 match value {
17 Some(value) => value,
18 None => &None::<Infallible>,
19 }
20}
21
22#[derive(Default, Clone, PartialEq, Eq, Hash)]
24pub struct Document<'text> {
25 pub nodes: Vec<Node<'text>>,
27}
28
29impl<'text> Document<'text> {
30 pub fn new() -> Self {
32 Self::default()
33 }
34 pub fn into_owned(self) -> Document<'static> {
36 Document {
37 nodes: self.nodes.into_iter().map(Node::into_owned).collect(),
38 }
39 }
40 pub fn get<'a, 'b>(&'a self, name: &'b str) -> impl Iterator<Item = &'a Node<'text>> + 'b
42 where
43 'text: 'a,
44 'a: 'b,
45 {
46 self.nodes.iter().filter(move |node| node.name() == name)
47 }
48 pub fn get_mut<'a, 'b>(&'a mut self, name: &'b str) -> impl Iterator<Item = &'a mut Node<'text>> + 'b
50 where
51 'text: 'a,
52 'a: 'b,
53 {
54 self.nodes.iter_mut().filter(move |node| node.name() == name)
55 }
56 pub fn parse(text: &'text str) -> Result<Self, Error> {
57 Ok(Parser::new(text).collect::<Result<Vec<_>, _>>()?.into_iter().collect())
58 }
59}
60
61impl fmt::Debug for Document<'_> {
62 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
63 f.write_str("Document ")?;
64 f.debug_list().entries(&self.nodes).finish()
65 }
66}
67impl fmt::Display for Document<'_> {
68 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
69 let mut iter = self.nodes.iter();
70 if let Some(first) = iter.next() {
71 write!(f, "{first}")?;
72 for node in iter {
73 write!(f, "\n{node}")?;
74 }
75 }
76 Ok(())
77 }
78}
79impl<'text> FromIterator<Event<'text>> for Document<'text> {
81 fn from_iter<T: IntoIterator<Item = Event<'text>>>(iter: T) -> Self {
82 let mut stack = vec![Document::new()];
83 for event in iter {
84 match event {
85 Event::Node { r#type, name } => {
86 let mut node = Node::new(name);
87 node.set_type_hint(r#type);
88 stack.last_mut().unwrap().nodes.push(node);
89 }
90 Event::Entry { r#type, key, value } => {
91 let mut entry = Entry::new_value(value);
92 entry.set_key(key);
93 entry.set_type_hint(r#type);
94 stack.last_mut().unwrap().nodes.last_mut().unwrap().entries.push(entry);
95 }
96 Event::Begin => stack.push(Document::new()),
97 Event::End => {
98 let children = stack.pop().unwrap();
99 stack.last_mut().unwrap().nodes.last_mut().unwrap().children = Some(children);
100 }
101 }
102 }
103 let document = stack.pop().unwrap();
104 assert!(stack.is_empty(), "invalid iterator stream");
105 document
106 }
107}
108
109#[derive(Clone, PartialEq, Eq, Hash)]
111pub struct Node<'text> {
112 r#type: Option<Cow<'text, str>>,
113 name: Cow<'text, str>,
114 pub entries: Vec<Entry<'text>>,
116 pub children: Option<Document<'text>>,
118}
119
120impl<'text> Node<'text> {
121 pub fn new(name: impl Into<Cow<'text, str>>) -> Self {
123 Self {
124 r#type: None,
125 name: name.into(),
126 entries: Vec::new(),
127 children: None,
128 }
129 }
130 pub fn into_owned(self) -> Node<'static> {
132 Node {
133 r#type: self.r#type.map(cow_static),
134 name: cow_static(self.name),
135 entries: self.entries.into_iter().map(Entry::into_owned).collect(),
136 children: self.children.map(Document::into_owned),
137 }
138 }
139 pub fn name(&self) -> &str {
141 &self.name
142 }
143 pub fn set_name(&mut self, name: impl Into<Cow<'text, str>>) {
145 self.name = name.into();
146 }
147 pub fn type_hint(&self) -> Option<&str> {
149 self.r#type.as_deref()
150 }
151 pub fn set_type_hint(&mut self, r#type: Option<impl Into<Cow<'text, str>>>) {
153 self.r#type = r#type.map(Into::into);
154 }
155 pub fn entry<'key>(&self, key: impl Into<EntryKey<'key>>) -> Option<&Entry<'text>> {
157 key.into().seek(self.entries.iter(), |ent| ent.key.as_deref())
158 }
159 pub fn entry_mut<'key>(&mut self, key: impl Into<EntryKey<'key>>) -> Option<&mut Entry<'text>> {
161 key.into().seek(self.entries.iter_mut(), |ent| ent.key.as_deref())
162 }
163 pub fn normalize(&mut self) {
168 if let Some(children) = &mut self.children {
169 if children.nodes.is_empty() {
170 self.children = None;
171 } else {
172 for node in &mut children.nodes {
173 node.normalize();
174 }
175 }
176 }
177 let marker = &"\0temp"[5..];
180 let mut seen = HashSet::new();
182 for entry in self.entries.iter_mut().rev() {
183 if let Some(key) = &mut entry.key {
184 if seen.contains(key) {
185 *key = Cow::Borrowed(marker);
186 } else {
187 seen.insert(&*key);
188 }
189 }
190 }
191 self.entries.retain(|ent| {
192 !ent
193 .key
194 .as_ref()
195 .is_some_and(|key| std::ptr::eq(key.as_ptr(), marker.as_ptr()) && key.is_empty())
196 });
197 }
198}
199
200impl fmt::Debug for Node<'_> {
201 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
202 f.debug_struct("Node")
203 .field("type", maybe_debug(self.type_hint().as_ref()))
204 .field("name", &self.name)
205 .field("props", &self.entries)
206 .field("children", maybe_debug(self.children.as_ref()))
207 .finish()
208 }
209}
210impl fmt::Display for Node<'_> {
211 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
212 if let Some(r#type) = &self.r#type {
213 write!(f, "({})", IdentDisplay(r#type))?;
214 }
215 fmt::Display::fmt(&IdentDisplay(&self.name), f)?;
216 for entry in &self.entries {
217 write!(f, " {entry}")?;
218 }
219 if let Some(children) = &self.children {
220 struct Children<'this>(&'this Document<'this>, Cell<bool>);
222 impl fmt::Debug for Children<'_> {
223 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
224 fmt::Display::fmt(self.0, f)?;
225 self.1.set(true);
228 Err(fmt::Error)
229 }
230 }
231 struct Block<'this>(&'this Document<'this>);
232 impl fmt::Debug for Block<'_> {
233 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
234 let children = Children(self.0, Cell::new(false));
235 let result = f.debug_set().entry(&children).finish();
236 if children.1.get() {
237 Ok(())
238 } else {
239 result
240 }
241 }
242 }
243 f.write_str(" ")?;
244 write!(f, "{:#?}\n}}", Block(children))?;
245 }
246 Ok(())
247 }
248}
249impl<'key, 'text, T: Into<EntryKey<'key>>> Index<T> for Node<'text> {
250 type Output = Entry<'text>;
251 fn index(&self, index: T) -> &Self::Output {
252 let key = index.into();
253 self
254 .entry(key)
255 .unwrap_or_else(|| panic!("Key {key:?} does not exist in node"))
256 }
257}
258impl<'key, 'text, T: Into<EntryKey<'key>>> IndexMut<T> for Node<'text> {
259 fn index_mut(&mut self, index: T) -> &mut Self::Output {
260 let key = index.into();
261 self
262 .entry_mut(key)
263 .unwrap_or_else(|| panic!("Key {key:?} does not exist in node"))
264 }
265}
266
267#[derive(Clone, PartialEq, Eq, Hash)]
269pub struct Entry<'text> {
270 key: Option<Cow<'text, str>>,
271 r#type: Option<Cow<'text, str>>,
272 pub value: Value<'text>,
274}
275
276impl<'text> Entry<'text> {
277 pub fn new_value(value: Value<'text>) -> Self {
279 Self {
280 key: None,
281 r#type: None,
282 value,
283 }
284 }
285 pub fn new_prop(name: impl Into<Cow<'text, str>>, value: Value<'text>) -> Self {
287 Self {
288 key: Some(name.into()),
289 r#type: None,
290 value,
291 }
292 }
293 pub fn into_owned(self) -> Entry<'static> {
295 Entry {
296 key: self.key.map(cow_static),
297 r#type: self.r#type.map(cow_static),
298 value: self.value.into_owned(),
299 }
300 }
301 pub fn key(&self) -> Option<&str> {
303 self.key.as_deref()
304 }
305 pub fn set_key(&mut self, key: Option<impl Into<Cow<'text, str>>>) {
307 self.key = key.map(Into::into);
308 }
309 pub fn type_hint(&self) -> Option<&str> {
311 self.r#type.as_deref()
312 }
313 pub fn set_type_hint(&mut self, r#type: Option<impl Into<Cow<'text, str>>>) {
315 self.r#type = r#type.map(Into::into);
316 }
317}
318
319impl fmt::Debug for Entry<'_> {
320 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
321 f.debug_struct("Property")
322 .field("key", &self.key)
323 .field("type", maybe_debug(self.type_hint().as_ref()))
324 .field("value", &self.value)
325 .finish()
326 }
327}
328impl fmt::Display for Entry<'_> {
329 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
330 if let Some(key) = &self.key {
331 write!(f, "{}=", IdentDisplay(key))?;
332 }
333 if let Some(r#type) = &self.r#type {
334 write!(f, "({})", IdentDisplay(r#type))?;
335 }
336 fmt::Display::fmt(&self.value, f)
337 }
338}
339impl<'text, K: Into<Cow<'text, str>>, V: Into<Value<'text>>> From<(K, V)> for Entry<'text> {
340 fn from((name, value): (K, V)) -> Self {
341 Self::new_prop(name.into(), value.into())
342 }
343}
344impl<'text, V: Into<Value<'text>>> From<V> for Entry<'text> {
345 fn from(value: V) -> Self {
346 Self::new_value(value.into())
347 }
348}
349
350#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
352pub enum EntryKey<'text> {
353 Pos(usize),
354 Name(&'text str),
355}
356impl EntryKey<'_> {
357 fn seek<T>(self, mut iter: impl DoubleEndedIterator<Item = T>, name: impl Fn(&T) -> Option<&str>) -> Option<T> {
358 match self {
359 EntryKey::Pos(key) => iter.filter(|ent| name(ent).is_none()).nth(key),
360 EntryKey::Name(key) => iter.rfind(|ent| name(ent) == Some(key)),
362 }
363 }
364}
365impl From<usize> for EntryKey<'_> {
366 fn from(value: usize) -> Self {
367 Self::Pos(value)
368 }
369}
370impl<'text> From<&'text str> for EntryKey<'text> {
371 fn from(value: &'text str) -> Self {
372 Self::Name(value)
373 }
374}
375
376fn norm_float(v: f64) -> u64 {
377 match v.classify() {
378 FpCategory::Nan => u64::MAX,
379 FpCategory::Zero => 0,
380 FpCategory::Infinite | FpCategory::Subnormal | FpCategory::Normal => v.to_bits(),
381 }
382}
383
384#[derive(Clone)]
386pub enum Value<'text> {
387 String(Cow<'text, str>),
389 Integer(i128),
391 Float(f64),
393 Bool(bool),
395 Null,
397}
398
399impl Value<'_> {
400 pub fn into_owned(self) -> Value<'static> {
402 match self {
403 Self::String(value) => Value::String(cow_static(value)),
404 Self::Integer(value) => Value::Integer(value),
405 Self::Float(value) => Value::Float(value),
406 Self::Bool(value) => Value::Bool(value),
407 Self::Null => Value::Null,
408 }
409 }
410 }
412
413impl fmt::Debug for Value<'_> {
414 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
415 match self {
416 Self::String(value) => fmt::Debug::fmt(&**value, f),
417 Self::Integer(value) => fmt::Debug::fmt(value, f),
418 Self::Float(value) => fmt::Debug::fmt(value, f),
419 Self::Bool(true) => f.write_str("#true"),
420 Self::Bool(false) => f.write_str("#false"),
421 Self::Null => f.write_str("#null"),
422 }
423 }
424}
425impl fmt::Display for Value<'_> {
426 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
427 match self {
428 Value::String(value) => fmt::Display::fmt(&IdentDisplay(value), f),
429 Value::Integer(value) => fmt::Display::fmt(value, f),
430 Value::Float(value) => match value.classify() {
431 FpCategory::Nan => f.write_str("#nan"),
432 FpCategory::Infinite => f.write_str(if value.is_sign_negative() { "#-inf" } else { "#inf" }),
433 FpCategory::Zero | FpCategory::Subnormal | FpCategory::Normal => {
434 fmt::Debug::fmt(&value, f)
436 }
437 },
438 Value::Bool(true) => f.write_str("#true"),
439 Value::Bool(false) => f.write_str("#false"),
440 Value::Null => f.write_str("#null"),
441 }
442 }
443}
444impl PartialEq for Value<'_> {
445 fn eq(&self, other: &Self) -> bool {
446 match (self, other) {
447 (Self::String(l), Self::String(r)) => l == r,
448 (Self::Integer(l), Self::Integer(r)) => l == r,
449 (Self::Float(l), Self::Float(r)) => norm_float(*l) == norm_float(*r),
450 (Self::Bool(l), Self::Bool(r)) => l == r,
451 (Self::Null, Self::Null) => true,
452 _ => false,
453 }
454 }
455}
456impl Eq for Value<'_> {}
457impl std::hash::Hash for Value<'_> {
458 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
459 match self {
460 Value::String(value) => {
461 state.write_u8(0);
462 value.hash(state);
463 }
464 Value::Integer(value) => {
465 state.write_u8(1);
466 value.hash(state);
467 }
468 Value::Float(value) => {
469 state.write_u8(2);
470 norm_float(*value).hash(state);
471 }
472 Value::Bool(value) => {
473 state.write_u8(3);
474 value.hash(state);
475 }
476 Value::Null => {
477 state.write_u8(4);
478 }
479 }
480 }
481}
482impl<'text> From<&'text str> for Value<'text> {
483 fn from(value: &'text str) -> Self {
484 Self::String(Cow::Borrowed(value))
485 }
486}
487impl<'text> From<String> for Value<'text> {
488 fn from(value: String) -> Self {
489 Self::String(Cow::Owned(value))
490 }
491}
492impl<'text> From<f64> for Value<'text> {
493 fn from(value: f64) -> Self {
494 Self::Float(value)
495 }
496}
497impl<'text> From<i128> for Value<'text> {
498 fn from(value: i128) -> Self {
499 Self::Integer(value)
500 }
501}
502impl<'text> From<bool> for Value<'text> {
503 fn from(value: bool) -> Self {
504 Self::Bool(value)
505 }
506}
507impl<'text> From<()> for Value<'text> {
508 fn from((): ()) -> Self {
509 Self::Null
510 }
511}
512impl<'text, T: Into<Value<'text>>> From<Option<T>> for Value<'text> {
513 fn from(value: Option<T>) -> Self {
514 match value {
515 Some(v) => v.into(),
516 _ => Self::Null,
517 }
518 }
519}