lightningcss/
dependencies.rs1use crate::css_modules::hash;
12use crate::printer::PrinterOptions;
13use crate::rules::import::ImportRule;
14use crate::traits::ToCss;
15use crate::values::url::Url;
16#[cfg(feature = "visitor")]
17use crate::visitor::Visit;
18use cssparser::SourceLocation;
19#[cfg(any(feature = "serde", feature = "nodejs"))]
20use serde::Serialize;
21
22#[derive(Default)]
24pub struct DependencyOptions {
25 pub remove_imports: bool,
27}
28
29#[derive(Debug)]
31#[cfg_attr(any(feature = "serde", feature = "nodejs"), derive(Serialize))]
32#[cfg_attr(
33 any(feature = "serde", feature = "nodejs"),
34 serde(tag = "type", rename_all = "lowercase")
35)]
36pub enum Dependency {
37 Import(ImportDependency),
39 Url(UrlDependency),
41}
42
43#[derive(Debug)]
45#[cfg_attr(any(feature = "serde", feature = "nodejs"), derive(Serialize))]
46pub struct ImportDependency {
47 pub url: String,
49 pub placeholder: String,
51 pub supports: Option<String>,
53 pub media: Option<String>,
55 pub loc: SourceRange,
57}
58
59impl ImportDependency {
60 pub fn new(rule: &ImportRule, filename: &str) -> ImportDependency {
62 let supports = if let Some(supports) = &rule.supports {
63 let s = supports.to_css_string(PrinterOptions::default()).unwrap();
64 Some(s)
65 } else {
66 None
67 };
68
69 let media = if !rule.media.media_queries.is_empty() {
70 let s = rule.media.to_css_string(PrinterOptions::default()).unwrap();
71 Some(s)
72 } else {
73 None
74 };
75
76 let placeholder = hash(&format!("{}_{}", filename, rule.url), false);
77
78 ImportDependency {
79 url: rule.url.as_ref().to_owned(),
80 placeholder,
81 supports,
82 media,
83 loc: SourceRange::new(
84 filename,
85 Location {
86 line: rule.loc.line + 1,
87 column: rule.loc.column,
88 },
89 8,
90 rule.url.len() + 2,
91 ), }
93 }
94}
95
96#[derive(Debug)]
98#[cfg_attr(any(feature = "serde", feature = "nodejs"), derive(Serialize))]
99pub struct UrlDependency {
100 pub url: String,
102 pub placeholder: String,
104 pub loc: SourceRange,
106}
107
108impl UrlDependency {
109 pub fn new(url: &Url, filename: &str) -> UrlDependency {
111 let placeholder = hash(&format!("{}_{}", filename, url.url), false);
112 UrlDependency {
113 url: url.url.to_string(),
114 placeholder,
115 loc: SourceRange::new(filename, url.loc, 4, url.url.len()),
116 }
117 }
118}
119
120#[derive(Debug)]
122#[cfg_attr(any(feature = "serde", feature = "nodejs"), derive(Serialize))]
123#[cfg_attr(any(feature = "serde", feature = "nodejs"), serde(rename_all = "camelCase"))]
124pub struct SourceRange {
125 pub file_path: String,
127 pub start: Location,
129 pub end: Location,
131}
132
133#[derive(Debug, Clone, Copy, PartialEq)]
135#[cfg_attr(feature = "visitor", derive(Visit))]
136#[cfg_attr(any(feature = "serde", feature = "nodejs"), derive(serde::Serialize))]
137#[cfg_attr(any(feature = "serde"), derive(serde::Deserialize))]
138#[cfg_attr(feature = "jsonschema", derive(schemars::JsonSchema))]
139#[cfg_attr(feature = "into_owned", derive(static_self::IntoOwned))]
140pub struct Location {
141 pub line: u32,
143 pub column: u32,
145}
146
147impl From<SourceLocation> for Location {
148 fn from(loc: SourceLocation) -> Location {
149 Location {
150 line: loc.line + 1,
151 column: loc.column,
152 }
153 }
154}
155
156impl SourceRange {
157 fn new(filename: &str, loc: Location, offset: u32, len: usize) -> SourceRange {
158 SourceRange {
159 file_path: filename.into(),
160 start: Location {
161 line: loc.line,
162 column: loc.column + offset,
163 },
164 end: Location {
165 line: loc.line,
166 column: loc.column + offset + (len as u32) - 1,
167 },
168 }
169 }
170}