biome_css_syntax/
stmt_ext.rs

1use crate::generated::{
2    CssDeclarationBlock, CssDeclarationOrAtRuleBlock, CssDeclarationOrRuleBlock,
3    CssFontFeatureValuesBlock, CssKeyframesBlock, CssPageAtRuleBlock, CssRuleBlock,
4};
5use crate::CssSyntaxToken;
6use biome_rowan::{declare_node_union, AstNodeList, SyntaxResult};
7
8declare_node_union! {
9    pub CssBlockLike = CssKeyframesBlock | CssDeclarationOrAtRuleBlock | CssDeclarationBlock | CssRuleBlock | CssFontFeatureValuesBlock | CssPageAtRuleBlock | CssDeclarationOrRuleBlock
10}
11
12impl CssBlockLike {
13    /// Retrieves the left curly token "{" of the css block-like.
14    pub fn l_curly_token(&self) -> SyntaxResult<CssSyntaxToken> {
15        match self {
16            CssBlockLike::CssKeyframesBlock(block) => block.l_curly_token(),
17            CssBlockLike::CssDeclarationOrAtRuleBlock(block) => block.l_curly_token(),
18            CssBlockLike::CssDeclarationBlock(block) => block.l_curly_token(),
19            CssBlockLike::CssRuleBlock(block) => block.l_curly_token(),
20            CssBlockLike::CssFontFeatureValuesBlock(block) => block.l_curly_token(),
21            CssBlockLike::CssPageAtRuleBlock(block) => block.l_curly_token(),
22            CssBlockLike::CssDeclarationOrRuleBlock(block) => block.l_curly_token(),
23        }
24    }
25
26    /// Retrieves the right curly token "}" of the css block-like.
27    pub fn r_curly_token(&self) -> SyntaxResult<CssSyntaxToken> {
28        match self {
29            CssBlockLike::CssKeyframesBlock(block) => block.r_curly_token(),
30            CssBlockLike::CssDeclarationOrAtRuleBlock(block) => block.r_curly_token(),
31            CssBlockLike::CssDeclarationBlock(block) => block.r_curly_token(),
32            CssBlockLike::CssRuleBlock(block) => block.r_curly_token(),
33            CssBlockLike::CssFontFeatureValuesBlock(block) => block.r_curly_token(),
34            CssBlockLike::CssPageAtRuleBlock(block) => block.r_curly_token(),
35            CssBlockLike::CssDeclarationOrRuleBlock(block) => block.r_curly_token(),
36        }
37    }
38
39    /// Checks if the css block-like is empty, even if it may have comments inside.
40    pub fn is_empty(&self) -> bool {
41        match self {
42            CssBlockLike::CssKeyframesBlock(block) => block.items().is_empty(),
43            CssBlockLike::CssDeclarationOrAtRuleBlock(block) => block.items().is_empty(),
44            CssBlockLike::CssDeclarationBlock(block) => block.declarations().is_empty(),
45            CssBlockLike::CssRuleBlock(block) => block.rules().is_empty(),
46            CssBlockLike::CssFontFeatureValuesBlock(block) => block.items().is_empty(),
47            CssBlockLike::CssPageAtRuleBlock(block) => block.items().is_empty(),
48            CssBlockLike::CssDeclarationOrRuleBlock(block) => block.items().is_empty(),
49        }
50    }
51
52    /// Checks if the css block-like is empty without comments inside.
53    pub fn is_empty_without_comments(&self) -> bool {
54        self.is_empty()
55            && !self
56                .l_curly_token()
57                .is_ok_and(|token| token.has_trailing_comments())
58            && !self
59                .r_curly_token()
60                .is_ok_and(|token| token.has_leading_comments())
61    }
62}