css_parse/syntax/
no_block_allowed.rs1use crate::{CursorSink, Diagnostic, KindSet, Parse, Parser, Peek, Result, SemanticEq, Span, T, ToCursors, ToSpan};
2use csskit_proc_macro::node;
3
4#[node]
14#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
15#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
16pub struct NoBlockAllowed<D = (), M = ()> {
17 semicolon: Option<crate::token_macros::Semicolon>,
18 _phantom: std::marker::PhantomData<(D, M)>,
19}
20
21impl<'a, D, M> Parse<'a> for NoBlockAllowed<D, M> {
22 fn parse<Iter>(p: &mut Parser<'a, Iter>) -> Result<Self>
23 where
24 Iter: Iterator<Item = crate::Cursor> + Clone,
25 {
26 if p.at_end() {
27 Ok(Self { semicolon: None, _phantom: std::marker::PhantomData })
28 } else if let Some(semicolon) = p.parse_if_peek::<T![;]>()? {
29 Ok(Self { semicolon: Some(semicolon), _phantom: std::marker::PhantomData })
30 } else {
31 Err(Diagnostic::new(p.next(), Diagnostic::unexpected))?
32 }
33 }
34}
35
36impl<'a, D, M> Peek<'a> for NoBlockAllowed<D, M> {
37 const PEEK_KINDSET: KindSet = KindSet::NONE;
38}
39
40impl<D, M> ToCursors for NoBlockAllowed<D, M> {
41 fn to_cursors(&self, s: &mut impl CursorSink) {
42 if let Some(semicolon) = self.semicolon {
43 s.append(semicolon.into());
44 }
45 }
46}
47
48impl<D, M> ToSpan for NoBlockAllowed<D, M> {
49 fn to_span(&self) -> Span {
50 self.semicolon.to_span()
51 }
52}
53
54impl<D, M> SemanticEq for NoBlockAllowed<D, M> {
55 fn semantic_eq(&self, other: &Self) -> bool {
56 self.semicolon.semantic_eq(&other.semicolon)
57 }
58}
59
60impl<D, M: crate::NodeMetadata> crate::NodeWithMetadata<M> for NoBlockAllowed<D, M> {
61 fn metadata(&self) -> M {
62 M::default()
63 }
64}
65
66impl<'a, D, M> crate::RuleVariants<'a> for NoBlockAllowed<D, M>
67where
68 D: crate::DeclarationValue<'a, M>,
69 M: crate::NodeMetadata,
70{
71 type DeclarationValue = D;
72 type Metadata = M;
73}