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 = Default::default();
69 loop {
70 if p.at_end() {
71 return Ok(Self { open_curly, declarations, close_curly: None, meta });
72 }
73 let close_curly = p.parse_if_peek::<T!['}']>()?;
74 if close_curly.is_some() {
75 return Ok(Self { open_curly, declarations, close_curly, meta });
76 }
77 let declaration = p.parse::<Declaration<'a, V, M>>()?;
78 meta.merge(&declaration.metadata());
79 declarations.push(declaration);
80 }
81 }
82}
83
84impl<'a, V, M> ToCursors for DeclarationList<'a, V, M>
85where
86 V: DeclarationValue<'a, M> + ToCursors,
87 M: NodeMetadata,
88{
89 fn to_cursors(&self, s: &mut impl CursorSink) {
90 ToCursors::to_cursors(&self.open_curly, s);
91 ToCursors::to_cursors(&self.declarations, s);
92 ToCursors::to_cursors(&self.close_curly, s);
93 }
94}
95
96impl<'a, V, M> ToSpan for DeclarationList<'a, V, M>
97where
98 V: DeclarationValue<'a, M> + ToSpan,
99 M: NodeMetadata,
100{
101 fn to_span(&self) -> Span {
102 self.open_curly.to_span()
103 + if let Some(close) = self.close_curly { close.to_span() } else { self.declarations.to_span() }
104 }
105}
106
107impl<'a, V, M> SemanticEq for DeclarationList<'a, V, M>
108where
109 V: DeclarationValue<'a, M>,
110 M: NodeMetadata,
111{
112 fn semantic_eq(&self, other: &Self) -> bool {
113 self.open_curly.semantic_eq(&other.open_curly)
114 && self.declarations.semantic_eq(&other.declarations)
115 && self.close_curly.semantic_eq(&other.close_curly)
116 }
117}