0
# Rust Library API
1
2
Direct Rust library interface providing low-level CSS parsing, transformation, and serialization capabilities with zero-cost abstractions and memory safety.
3
4
## Capabilities
5
6
### StyleSheet Parsing and Transformation
7
8
Core stylesheet parsing, minification, and serialization with configurable options and error handling.
9
10
```rust { .api }
11
use lightningcss::{
12
stylesheet::{StyleSheet, MinifyOptions, ParserOptions, PrinterOptions, ToCssResult},
13
error::{Error, ParserError, MinifyErrorKind, PrinterErrorKind},
14
traits::{Parse, ToCss},
15
};
16
17
impl<'i, 'o, T> StyleSheet<'i, 'o, T>
18
where
19
T: crate::traits::AtRuleParser<'i>
20
{
21
/// Parse a CSS stylesheet from a string
22
pub fn parse(
23
css: &'i str,
24
options: ParserOptions<'o, 'i>
25
) -> Result<Self, Error<ParserError<'i>>>;
26
27
/// Minify the stylesheet in-place
28
pub fn minify(&mut self, options: MinifyOptions) -> Result<(), Error<MinifyErrorKind>>;
29
30
/// Serialize the stylesheet to CSS
31
pub fn to_css(&self, options: PrinterOptions) -> Result<ToCssResult, Error<PrinterErrorKind>>;
32
33
/// Get the rules in this stylesheet
34
pub fn rules(&self) -> &crate::rules::CssRuleList<'i, 'o, T>;
35
36
/// Get mutable access to the rules in this stylesheet
37
pub fn rules_mut(&mut self) -> &mut crate::rules::CssRuleList<'i, 'o, T>;
38
}
39
40
/// Configuration options for CSS parsing
41
pub struct ParserOptions<'o, 'i> {
42
/// The filename being parsed, used for error messages
43
pub filename: &'i str,
44
/// CSS Modules configuration
45
pub css_modules: Option<crate::css_modules::CssModulesConfig<'o>>,
46
/// Source index for source maps
47
pub source_index: u32,
48
/// Whether to recover from parse errors
49
pub error_recovery: bool,
50
/// Optional warnings collection
51
pub warnings: Option<&'o mut Vec<Error<ParserError<'i>>>>,
52
/// Parser feature flags
53
pub flags: crate::parser::ParserFlags,
54
}
55
56
/// Options for CSS minification
57
pub struct MinifyOptions {
58
/// Browser targets for optimization
59
pub targets: Option<crate::targets::Targets>,
60
/// List of unused symbols to remove
61
pub unused_symbols: std::collections::HashSet<String>,
62
}
63
64
/// Options for CSS serialization/printing
65
pub struct PrinterOptions<'a> {
66
/// Whether to minify the output
67
pub minify: bool,
68
/// Whether to include source map information
69
pub source_map: Option<&'a mut crate::sourcemap::SourceMap>,
70
/// Project root for source map paths
71
pub project_root: Option<&'a str>,
72
/// Browser targets for vendor prefixes
73
pub targets: Option<crate::targets::Targets>,
74
/// Whether to analyze dependencies
75
pub analyze_dependencies: Option<crate::dependencies::DependencyOptions<'a>>,
76
/// Pseudo-class replacements
77
pub pseudo_classes: Option<crate::properties::ui::PseudoClasses<'a>>,
78
}
79
80
/// Result of CSS serialization
81
pub struct ToCssResult {
82
/// The serialized CSS code
83
pub code: String,
84
/// Extracted dependencies, if enabled
85
pub dependencies: Option<Vec<crate::dependencies::Dependency>>,
86
/// CSS module exports, if enabled
87
pub exports: Option<crate::css_modules::CssModuleExports>,
88
/// CSS module references, if enabled
89
pub references: Option<crate::css_modules::CssModuleReferences>,
90
}
91
```
92
93
**Usage Examples:**
94
95
```rust
96
use lightningcss::{
97
stylesheet::{StyleSheet, MinifyOptions, ParserOptions, PrinterOptions},
98
targets::Targets,
99
};
100
101
// Basic parsing and minification
102
fn process_css(css: &str) -> Result<String, Box<dyn std::error::Error>> {
103
let mut stylesheet = StyleSheet::parse(css, ParserOptions::default())?;
104
105
stylesheet.minify(MinifyOptions::default())?;
106
107
let result = stylesheet.to_css(PrinterOptions {
108
minify: true,
109
..PrinterOptions::default()
110
})?;
111
112
Ok(result.code)
113
}
114
115
// Advanced configuration
116
fn process_with_targets(css: &str) -> Result<String, Box<dyn std::error::Error>> {
117
let mut warnings = Vec::new();
118
119
let mut stylesheet = StyleSheet::parse(css, ParserOptions {
120
filename: "input.css",
121
error_recovery: true,
122
warnings: Some(&mut warnings),
123
..ParserOptions::default()
124
})?;
125
126
let targets = Targets {
127
chrome: Some(80 << 16),
128
firefox: Some(75 << 16),
129
safari: Some(13 << 16),
130
..Targets::default()
131
};
132
133
stylesheet.minify(MinifyOptions {
134
targets: Some(targets.clone()),
135
unused_symbols: ["unused-class", "old-animation"].iter().map(|s| s.to_string()).collect(),
136
})?;
137
138
let result = stylesheet.to_css(PrinterOptions {
139
minify: true,
140
targets: Some(targets),
141
..PrinterOptions::default()
142
})?;
143
144
// Handle warnings
145
for warning in warnings {
146
eprintln!("Warning: {:?}", warning);
147
}
148
149
Ok(result.code)
150
}
151
```
152
153
### Browser Targets
154
155
Rust-native browser targeting for CSS transformation and vendor prefixing.
156
157
```rust { .api }
158
use lightningcss::targets::{Targets, Browsers};
159
160
/// Browser compatibility targets
161
#[derive(Debug, Clone, Default)]
162
pub struct Targets {
163
pub android: Option<u32>,
164
pub chrome: Option<u32>,
165
pub edge: Option<u32>,
166
pub firefox: Option<u32>,
167
pub ie: Option<u32>,
168
pub ios_saf: Option<u32>,
169
pub opera: Option<u32>,
170
pub safari: Option<u32>,
171
pub samsung: Option<u32>,
172
}
173
174
impl Targets {
175
/// Create targets from browser versions
176
pub fn new(browsers: &Browsers) -> Self;
177
178
/// Check if a specific feature is supported
179
pub fn is_compatible(&self, feature: crate::compat::Feature) -> bool;
180
181
/// Get the minimum browser versions
182
pub fn browsers(&self) -> Browsers;
183
}
184
185
/// Browser version specifications
186
#[derive(Debug, Clone, Default)]
187
pub struct Browsers {
188
pub android: Option<f32>,
189
pub chrome: Option<f32>,
190
pub edge: Option<f32>,
191
pub firefox: Option<f32>,
192
pub ie: Option<f32>,
193
pub ios_saf: Option<f32>,
194
pub opera: Option<f32>,
195
pub safari: Option<f32>,
196
pub samsung: Option<f32>,
197
}
198
```
199
200
**Usage Examples:**
201
202
```rust
203
use lightningcss::targets::{Targets, Browsers};
204
205
// Direct target creation
206
let targets = Targets {
207
chrome: Some(90 << 16),
208
firefox: Some(88 << 16),
209
safari: Some(14 << 16),
210
..Targets::default()
211
};
212
213
// From browser versions
214
let browsers = Browsers {
215
chrome: Some(90.0),
216
firefox: Some(88.0),
217
safari: Some(14.0),
218
..Browsers::default()
219
};
220
let targets = Targets::new(&browsers);
221
222
// Feature compatibility checking
223
let supports_grid = targets.is_compatible(crate::compat::Feature::CssGrid);
224
```
225
226
### CSS Bundling
227
228
Rust API for bundling CSS files with dependency resolution and @import inlining.
229
230
```rust { .api }
231
#[cfg(feature = "bundler")]
232
use lightningcss::bundler::{Bundler, BundleErrorKind, FileProvider, SourceProvider};
233
234
/// CSS bundler for combining multiple files
235
pub struct Bundler<'a, 'o, 's, P, T>
236
where
237
P: SourceProvider,
238
T: crate::traits::AtRuleParser<'a>
239
{
240
/// Create a new bundler with a source provider
241
pub fn new(provider: &'s P, source_map: Option<&'s mut crate::sourcemap::SourceMap>) -> Self;
242
243
/// Bundle a CSS file and its dependencies
244
pub fn bundle(
245
&mut self,
246
fs_path: &std::path::Path,
247
options: crate::stylesheet::ParserOptions<'o, 'a>
248
) -> Result<crate::stylesheet::StyleSheet<'a, 'o, T>, BundleErrorKind<'a, std::io::Error>>;
249
}
250
251
/// Trait for providing CSS source content
252
pub trait SourceProvider: Send + Sync {
253
type Error: std::error::Error + Send + Sync + 'static;
254
255
/// Read CSS content from a file path
256
fn read<'a>(&'a self, file: &std::path::Path) -> Result<std::borrow::Cow<'a, str>, Self::Error>;
257
}
258
259
/// File system source provider
260
pub struct FileProvider {
261
/// Create a new file provider
262
pub fn new() -> Self;
263
}
264
265
impl SourceProvider for FileProvider {
266
type Error = std::io::Error;
267
268
fn read<'a>(&'a self, file: &std::path::Path) -> Result<std::borrow::Cow<'a, str>, Self::Error> {
269
std::fs::read_to_string(file).map(std::borrow::Cow::Owned)
270
}
271
}
272
```
273
274
**Usage Examples:**
275
276
```rust
277
#[cfg(feature = "bundler")]
278
use lightningcss::bundler::{Bundler, FileProvider};
279
use lightningcss::stylesheet::{ParserOptions, PrinterOptions};
280
use std::path::Path;
281
282
#[cfg(feature = "bundler")]
283
fn bundle_css(entry_path: &Path) -> Result<String, Box<dyn std::error::Error>> {
284
let fs = FileProvider::new();
285
let mut bundler = Bundler::new(&fs, None);
286
287
let stylesheet = bundler.bundle(entry_path, ParserOptions::default())?;
288
289
let result = stylesheet.to_css(PrinterOptions {
290
minify: true,
291
..PrinterOptions::default()
292
})?;
293
294
Ok(result.code)
295
}
296
297
// Custom source provider
298
#[cfg(feature = "bundler")]
299
struct DatabaseProvider {
300
// Custom implementation
301
}
302
303
#[cfg(feature = "bundler")]
304
impl SourceProvider for DatabaseProvider {
305
type Error = Box<dyn std::error::Error>;
306
307
fn read<'a>(&'a self, file: &std::path::Path) -> Result<std::borrow::Cow<'a, str>, Self::Error> {
308
// Read from database, cache, etc.
309
let content = fetch_from_database(file)?;
310
Ok(std::borrow::Cow::Owned(content))
311
}
312
}
313
```
314
315
### Style Attribute Processing
316
317
Parse and transform individual CSS declaration lists for style attributes.
318
319
```rust { .api }
320
use lightningcss::stylesheet::StyleAttribute;
321
322
/// Parser for CSS declaration lists (style attributes)
323
pub struct StyleAttribute<'i> {
324
/// Parse a declaration list from a string
325
pub fn parse(
326
input: &'i str,
327
options: crate::stylesheet::ParserOptions<'_, 'i>
328
) -> Result<Self, crate::error::Error<crate::error::ParserError<'i>>>;
329
330
/// Minify the declarations in-place
331
pub fn minify(
332
&mut self,
333
options: crate::stylesheet::MinifyOptions
334
) -> Result<(), crate::error::Error<crate::error::MinifyErrorKind>>;
335
336
/// Serialize to CSS
337
pub fn to_css(
338
&self,
339
options: crate::stylesheet::PrinterOptions
340
) -> Result<crate::stylesheet::ToCssResult, crate::error::Error<crate::error::PrinterErrorKind>>;
341
342
/// Get the declarations
343
pub fn declarations(&self) -> &crate::declaration::DeclarationBlock<'i>;
344
345
/// Get mutable access to declarations
346
pub fn declarations_mut(&mut self) -> &mut crate::declaration::DeclarationBlock<'i>;
347
}
348
```
349
350
**Usage Examples:**
351
352
```rust
353
use lightningcss::stylesheet::{StyleAttribute, ParserOptions, MinifyOptions, PrinterOptions};
354
355
fn process_style_attribute(style: &str) -> Result<String, Box<dyn std::error::Error>> {
356
let mut declarations = StyleAttribute::parse(style, ParserOptions::default())?;
357
358
declarations.minify(MinifyOptions::default())?;
359
360
let result = declarations.to_css(PrinterOptions {
361
minify: true,
362
..PrinterOptions::default()
363
})?;
364
365
Ok(result.code)
366
}
367
368
// Example: "color: red; background: blue; margin: 10px 20px 10px 20px"
369
// Result: "color:red;background:blue;margin:10px 20px"
370
```
371
372
### Error Handling
373
374
Comprehensive error types for different CSS processing stages.
375
376
```rust { .api }
377
use lightningcss::error::{Error, ErrorLocation, ParserError, MinifyErrorKind, PrinterErrorKind};
378
379
/// Generic error wrapper with location information
380
pub struct Error<T> {
381
/// The error kind
382
pub kind: T,
383
/// Source location where error occurred
384
pub loc: Option<ErrorLocation>,
385
}
386
387
/// Source location information
388
pub struct ErrorLocation {
389
/// Filename where error occurred
390
pub filename: String,
391
/// Line number (1-based)
392
pub line: u32,
393
/// Column number (1-based)
394
pub column: u32,
395
}
396
397
/// CSS parsing errors
398
pub enum ParserError<'i> {
399
/// Unexpected token during parsing
400
UnexpectedToken(cssparser::Token<'i>),
401
/// Unexpected EOF
402
UnexpectedEOF,
403
/// Invalid selector
404
SelectorError(crate::error::SelectorError<'i>),
405
/// Invalid at-rule
406
InvalidAtRule(std::borrow::Cow<'i, str>),
407
/// Invalid declaration
408
InvalidDeclaration,
409
/// Invalid value for property
410
InvalidValue,
411
/// Invalid media query
412
InvalidMediaQuery(cssparser::ParseError<'i, cssparser::BasicParseError<'i>>),
413
// ... more error variants
414
}
415
416
/// CSS minification errors
417
pub enum MinifyErrorKind {
418
/// Circular dependency in @import rules
419
CircularImport,
420
/// Invalid property value during minification
421
InvalidPropertyValue,
422
// ... more error variants
423
}
424
425
/// CSS printing/serialization errors
426
pub enum PrinterErrorKind {
427
/// I/O error during output
428
Io(std::io::Error),
429
/// Invalid UTF-8 in output
430
InvalidUtf8,
431
// ... more error variants
432
}
433
```
434
435
**Usage Examples:**
436
437
```rust
438
use lightningcss::{
439
stylesheet::{StyleSheet, ParserOptions},
440
error::{Error, ParserError, ErrorLocation},
441
};
442
443
fn handle_css_errors(css: &str) {
444
match StyleSheet::parse(css, ParserOptions::default()) {
445
Ok(stylesheet) => {
446
println!("Parsed successfully");
447
}
448
Err(Error { kind, loc }) => {
449
match kind {
450
ParserError::UnexpectedToken(token) => {
451
println!("Unexpected token: {:?}", token);
452
}
453
ParserError::InvalidDeclaration => {
454
println!("Invalid CSS declaration");
455
}
456
ParserError::SelectorError(sel_err) => {
457
println!("Invalid selector: {:?}", sel_err);
458
}
459
_ => {
460
println!("Parse error: {:?}", kind);
461
}
462
}
463
464
if let Some(ErrorLocation { filename, line, column }) = loc {
465
println!(" at {}:{}:{}", filename, line, column);
466
}
467
}
468
}
469
}
470
```
471
472
### Trait Implementations
473
474
Core traits for parsing and serialization that can be implemented for custom types.
475
476
```rust { .api }
477
use lightningcss::traits::{Parse, ToCss};
478
479
/// Trait for parsing CSS values from tokens
480
pub trait Parse<'i>: Sized {
481
/// Parse this value from a CSS parser
482
fn parse<'t>(input: &mut cssparser::Parser<'i, 't>) -> Result<Self, cssparser::ParseError<'i, Self::Error>>;
483
484
/// Associated error type for parsing failures
485
type Error: 'i;
486
}
487
488
/// Trait for serializing values to CSS
489
pub trait ToCss {
490
/// Write this value as CSS to the given destination
491
fn to_css<W>(&self, dest: &mut crate::printer::Printer<W>) -> Result<(), crate::error::PrinterError>
492
where W: std::fmt::Write;
493
494
/// Convert to a CSS string
495
fn to_css_string(&self) -> Result<String, crate::error::PrinterError> {
496
let mut s = String::new();
497
let mut printer = crate::printer::Printer::new(&mut s, crate::printer::PrinterOptions::default());
498
self.to_css(&mut printer)?;
499
Ok(s)
500
}
501
}
502
```
503
504
**Usage Examples:**
505
506
```rust
507
use lightningcss::traits::{Parse, ToCss};
508
use cssparser::{Parser, Token};
509
510
// Custom CSS value type
511
#[derive(Debug, Clone)]
512
struct CustomLength {
513
value: f32,
514
unit: String,
515
}
516
517
impl<'i> Parse<'i> for CustomLength {
518
type Error = ();
519
520
fn parse<'t>(input: &mut Parser<'i, 't>) -> Result<Self, cssparser::ParseError<'i, Self::Error>> {
521
match input.next()? {
522
Token::Dimension { value, unit, .. } => {
523
Ok(CustomLength {
524
value: *value,
525
unit: unit.to_string(),
526
})
527
}
528
_ => Err(input.new_custom_error(())),
529
}
530
}
531
}
532
533
impl ToCss for CustomLength {
534
fn to_css<W>(&self, dest: &mut crate::printer::Printer<W>) -> Result<(), crate::error::PrinterError>
535
where W: std::fmt::Write {
536
write!(dest, "{}{}", self.value, self.unit)?;
537
Ok(())
538
}
539
}
540
541
// Usage
542
fn parse_custom_length(css: &str) -> Result<CustomLength, Box<dyn std::error::Error>> {
543
let mut input = cssparser::ParserInput::new(css);
544
let mut parser = cssparser::Parser::new(&mut input);
545
Ok(CustomLength::parse(&mut parser)?)
546
}
547
```