1use crate::{
2 CursorSink, Declaration, DeclarationValue, Kind, KindSet, NodeMetadata, NodeWithMetadata, Parse, Parser, Peek,
3 Result, SemanticEq, Span, T, ToCursors, ToSpan, token_macros,
4};
5use bumpalo::collections::Vec;
6
7#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
25#[cfg_attr(feature = "serde", derive(serde::Serialize))]
26#[cfg_attr(feature = "serde", serde(bound(serialize = "V: serde::Serialize")))]
27pub struct DeclarationList<'a, V, M>
28where
29 V: DeclarationValue<'a, M>,
30 M: NodeMetadata,
31{
32 pub open_curly: token_macros::LeftCurly,
33 pub declarations: Vec<'a, Declaration<'a, V, M>>,
34 pub close_curly: Option<token_macros::RightCurly>,
35 #[cfg_attr(feature = "serde", serde(skip))]
36 meta: M,
37}
38
39impl<'a, V, M> NodeWithMetadata<M> for DeclarationList<'a, V, M>
40where
41 V: DeclarationValue<'a, M>,
42 M: NodeMetadata,
43{
44 fn metadata(&self) -> M {
45 self.meta
46 }
47}
48
49impl<'a, V, M> Peek<'a> for DeclarationList<'a, V, M>
50where
51 V: DeclarationValue<'a, M>,
52 M: NodeMetadata,
53{
54 const PEEK_KINDSET: KindSet = KindSet::new(&[Kind::LeftCurly]);
55}
56
57impl<'a, V, M> Parse<'a> for DeclarationList<'a, V, M>
58where
59 V: DeclarationValue<'a, M>,
60 M: NodeMetadata,
61{
62 fn parse<Iter>(p: &mut Parser<'a, Iter>) -> Result<Self>
63 where
64 Iter: Iterator<Item = crate::Cursor> + Clone,
65 {
66 let open_curly = p.parse::<T!['{']>()?;
67 let mut declarations = Vec::new_in(p.bump());
68 let mut meta: M = Default::default();
69 loop {
70 if p.at_end() {
71 meta = meta.with_size(declarations.len().min(u16::MAX as usize) as u16);
72 return Ok(Self { open_curly, declarations, close_curly: None, meta });
73 }
74 let close_curly = p.parse_if_peek::<T!['}']>()?;
75 if close_curly.is_some() {
76 meta = meta.with_size(declarations.len().min(u16::MAX as usize) as u16);
77 return Ok(Self { open_curly, declarations, close_curly, meta });
78 }
79 let declaration = p.parse::<Declaration<'a, V, M>>()?;
80 meta = meta.merge(declaration.metadata());
81 declarations.push(declaration);
82 }
83 }
84}
85
86impl<'a, V, M> ToCursors for DeclarationList<'a, V, M>
87where
88 V: DeclarationValue<'a, M> + ToCursors,
89 M: NodeMetadata,
90{
91 fn to_cursors(&self, s: &mut impl CursorSink) {
92 ToCursors::to_cursors(&self.open_curly, s);
93 ToCursors::to_cursors(&self.declarations, s);
94 ToCursors::to_cursors(&self.close_curly, s);
95 }
96}
97
98impl<'a, V, M> ToSpan for DeclarationList<'a, V, M>
99where
100 V: DeclarationValue<'a, M> + ToSpan,
101 M: NodeMetadata,
102{
103 fn to_span(&self) -> Span {
104 self.open_curly.to_span()
105 + if let Some(close) = self.close_curly { close.to_span() } else { self.declarations.to_span() }
106 }
107}
108
109impl<'a, V, M> SemanticEq for DeclarationList<'a, V, M>
110where
111 V: DeclarationValue<'a, M>,
112 M: NodeMetadata,
113{
114 fn semantic_eq(&self, other: &Self) -> bool {
115 self.open_curly.semantic_eq(&other.open_curly)
116 && self.declarations.semantic_eq(&other.declarations)
117 && self.close_curly.semantic_eq(&other.close_curly)
118 }
119}