css_ast/rules/
import.rs

1use super::prelude::*;
2use crate::{LayerName, MediaQueryList, SupportsCondition, UrlOrString};
3
4/// <https://drafts.csswg.org/css-cascade-5/#at-ruledef-import>
5///
6/// ```text
7/// @import [ <url> | <string> ]
8///  [ layer | layer(<layer-name>) ]?
9///  <import-conditions> ;
10///
11/// <import-conditions>  = [ supports( [ <supports-condition> | <declaration> ] ) ]?
12///                      <media-query-list>?
13/// ```
14#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
15#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
16#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit)]
17#[derive(csskit_derives::NodeWithMetadata)]
18pub struct ImportRule<'a> {
19	#[cfg_attr(feature = "visitable", visit(skip))]
20	#[atom(CssAtomSet::Import)]
21	pub name: T![AtKeyword],
22	pub url: UrlOrString,
23	pub layer: Option<ImportLayer<'a>>,
24	pub supports_condition: Option<ImportSupportsFunction<'a>>,
25	pub media_condition: Option<MediaQueryList<'a>>,
26	#[cfg_attr(feature = "visitable", visit(skip))]
27	pub semicolon: Option<T![;]>,
28}
29
30#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
31#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
32#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
33#[derive(csskit_derives::NodeWithMetadata)]
34pub enum ImportLayer<'a> {
35	#[atom(CssAtomSet::Layer)]
36	#[cfg_attr(feature = "visitable", visit(skip))]
37	Layer(T![Ident]),
38	#[atom(CssAtomSet::Layer)]
39	LayerFunction(ImportLayerFunction<'a>),
40}
41
42#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
43#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
44#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit)]
45#[derive(csskit_derives::NodeWithMetadata)]
46pub struct ImportLayerFunction<'a> {
47	#[atom(CssAtomSet::Layer)]
48	#[cfg_attr(feature = "visitable", visit(skip))]
49	pub name: T![Function],
50	pub layer: LayerName<'a>,
51	#[cfg_attr(feature = "visitable", visit(skip))]
52	pub close: T![')'],
53}
54
55#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
56#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
57#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit)]
58#[derive(csskit_derives::NodeWithMetadata)]
59pub struct ImportSupportsFunction<'a> {
60	#[atom(CssAtomSet::Supports)]
61	#[cfg_attr(feature = "visitable", visit(skip))]
62	pub name: T![Function],
63	pub condition: SupportsCondition<'a>,
64	#[cfg_attr(feature = "visitable", visit(skip))]
65	pub close: T![')'],
66}
67
68#[cfg(test)]
69mod tests {
70	use super::*;
71	use css_parse::assert_parse;
72
73	#[test]
74	fn size_test() {
75		assert_eq!(std::mem::size_of::<ImportRule>(), 744);
76	}
77
78	#[test]
79	fn test_writes() {
80		assert_parse!(CssAtomSet::ATOMS, ImportRule, "@import \"foo.css\";");
81		assert_parse!(CssAtomSet::ATOMS, ImportRule, "@import url(\"foo.css\");");
82		assert_parse!(CssAtomSet::ATOMS, ImportRule, "@import url(\"foo.css\") print;");
83		assert_parse!(CssAtomSet::ATOMS, ImportRule, "@import url('foo.css') projection, tv;");
84		assert_parse!(CssAtomSet::ATOMS, ImportRule, "@import url('foo.css') handheld and (max-width: 400px);");
85		assert_parse!(CssAtomSet::ATOMS, ImportRule, "@import url('foo.css') supports(not (display: flex));");
86		assert_parse!(
87			CssAtomSet::ATOMS,
88			ImportRule,
89			"@import url('foo.css') layer supports(not (display: flex)) media, print;"
90		);
91		assert_parse!(
92			CssAtomSet::ATOMS,
93			ImportRule,
94			"@import url('foo.css') layer(main) supports(not (display: flex)) media, print;"
95		);
96	}
97}