Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ jobs:
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v1
- run: cargo fmt
- run: cargo test
- run: cargo test --all-features
4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,13 @@ indoc = "1.0.3"
assert_cmd = "2.0"
assert_fs = "1.0"
predicates = "2.1"
serde_json = "1.0.78"

[features]
default = ["grid"]
cli = ["clap", "serde_json", "pathdiff", "browserslist-rs", "jemallocator"]
grid = []
serde = ["smallvec/serde", "cssparser/serde"]

[[test]]
name = "cli_integration_tests"
Expand Down
20 changes: 20 additions & 0 deletions examples/serialize.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
fn main() {
parse();
}

#[cfg(feature = "serde")]
fn parse() {
use parcel_css::stylesheet::{ParserOptions, StyleSheet};
use std::{env, fs};

let args: Vec<String> = env::args().collect();
let contents = fs::read_to_string(&args[1]).unwrap();
let stylesheet = StyleSheet::parse(&args[1], &contents, ParserOptions::default()).unwrap();
let json = serde_json::to_string(&stylesheet).unwrap();
println!("{}", json);
}

#[cfg(not(feature = "serde"))]
fn parse() {
panic!("serde feature is not enabled")
}
2 changes: 2 additions & 0 deletions src/declaration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@ use cssparser::*;
/// and a list of normal declarations. This reduces memory usage compared
/// with storing a boolean along with each property.
#[derive(Debug, PartialEq, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct DeclarationBlock<'i> {
/// A list of `!important` declarations in the block.
#[cfg_attr(feature = "serde", serde(borrow))]
pub important_declarations: Vec<Property<'i>>,
/// A list of normal declarations in the block.
pub declarations: Vec<Property<'i>>,
Expand Down
24 changes: 17 additions & 7 deletions src/dependencies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ impl ImportDependency {
media,
loc: SourceRange::new(
filename,
SourceLocation {
line: rule.loc.line,
Location {
line: rule.loc.line + 1,
column: rule.loc.column,
},
8,
Expand Down Expand Up @@ -109,24 +109,34 @@ pub struct SourceRange {
}

/// A line and column position within a source file.
#[derive(Serialize)]
#[derive(Serialize, Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
pub struct Location {
/// The line number, starting from 0.
/// The line number, starting from 1.
pub line: u32,
/// The column number, starting from 1.
pub column: u32,
}

impl From<SourceLocation> for Location {
fn from(loc: SourceLocation) -> Location {
Location {
line: loc.line + 1,
column: loc.column,
}
}
}

impl SourceRange {
fn new(filename: &str, loc: SourceLocation, offset: u32, len: usize) -> SourceRange {
fn new(filename: &str, loc: Location, offset: u32, len: usize) -> SourceRange {
SourceRange {
file_path: filename.into(),
start: Location {
line: loc.line + 1,
line: loc.line,
column: loc.column + offset,
},
end: Location {
line: loc.line + 1,
line: loc.line,
column: loc.column + offset + (len as u32) - 1,
},
}
Expand Down
2 changes: 2 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use std::fmt;

/// An error with a source location.
#[derive(Debug, PartialEq, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Error<T> {
/// The type of error that occurred.
pub kind: T,
Expand All @@ -31,6 +32,7 @@ impl<T: fmt::Display + fmt::Debug> std::error::Error for Error<T> {}

/// A line and column location within a source file.
#[derive(Debug, PartialEq, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ErrorLocation {
/// The filename in which the error occurred.
pub filename: String,
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14291,7 +14291,7 @@ mod tests {
);
error_test(
"@-moz-document url-prefix(\"foo\") {}",
ParserError::UnexpectedToken(crate::properties::custom::Token::QuotedString("foo".into())),
ParserError::UnexpectedToken(crate::properties::custom::Token::String("foo".into())),
);
}

Expand Down
5 changes: 5 additions & 0 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ macro_rules! enum_property {
) => {
$(#[$outer])*
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize), serde(rename_all = "lowercase"))]
$vis enum $name {
$(
$(#[$meta])*
Expand Down Expand Up @@ -66,9 +67,11 @@ macro_rules! enum_property {
) => {
$(#[$outer])*
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
$vis enum $name {
$(
$(#[$meta])*
#[cfg_attr(feature = "serde", serde(rename = $str))]
$id,
)+
}
Expand Down Expand Up @@ -319,6 +322,7 @@ macro_rules! define_shorthand {
) => {
$(#[$outer])*
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct $name$(<$l>)? {
$(
$(#[$meta])*
Expand Down Expand Up @@ -532,6 +536,7 @@ macro_rules! define_list_shorthand {
) => {
$(#[$outer])*
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct $name$(<$l>)? {
$(
$(#[$meta])*
Expand Down
33 changes: 33 additions & 0 deletions src/media_query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ use std::collections::{HashMap, HashSet};

/// A [media query list](https://drafts.csswg.org/mediaqueries/#mq-list).
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct MediaList<'i> {
/// The list of media queries.
#[cfg_attr(feature = "serde", serde(borrow))]
pub media_queries: Vec<MediaQuery<'i>>,
}

Expand Down Expand Up @@ -141,6 +143,11 @@ enum_property! {

/// A [media type](https://drafts.csswg.org/mediaqueries/#media-types) within a media query.
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize),
serde(tag = "type", content = "value", rename_all = "kebab-case")
)]
pub enum MediaType<'i> {
/// Matches all devices.
All,
Expand All @@ -150,6 +157,7 @@ pub enum MediaType<'i> {
/// Matches all devices that aren’t matched by print.
Screen,
/// An unknown media type.
#[cfg_attr(feature = "serde", serde(borrow))]
Custom(CowArcStr<'i>),
}

Expand All @@ -167,10 +175,12 @@ impl<'i> Parse<'i> for MediaType<'i> {

/// A [media query](https://drafts.csswg.org/mediaqueries/#media).
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct MediaQuery<'i> {
/// The qualifier for this query.
pub qualifier: Option<Qualifier>,
/// The media type for this query, that can be known, unknown, or "all".
#[cfg_attr(feature = "serde", serde(borrow))]
pub media_type: MediaType<'i>,
/// The condition that this media query contains. This cannot have `or`
/// in the first level.
Expand Down Expand Up @@ -354,8 +364,14 @@ enum_property! {

/// Represents a media condition.
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize),
serde(tag = "type", content = "value", rename_all = "kebab-case")
)]
pub enum MediaCondition<'i> {
/// A media feature, implicitly parenthesized.
#[cfg_attr(feature = "serde", serde(borrow))]
Feature(MediaFeature<'i>),
/// A negation of a condition.
Not(Box<MediaCondition<'i>>),
Expand Down Expand Up @@ -460,6 +476,11 @@ impl<'i> ToCss for MediaCondition<'i> {

/// A [comparator](https://drafts.csswg.org/mediaqueries/#typedef-mf-comparison) within a media query.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize),
serde(tag = "type", content = "value", rename_all = "kebab-case")
)]
pub enum MediaFeatureComparison {
/// `=`
Equal,
Expand Down Expand Up @@ -511,10 +532,16 @@ impl MediaFeatureComparison {

/// A [media feature](https://drafts.csswg.org/mediaqueries/#typedef-media-feature)
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize),
serde(tag = "type", content = "value", rename_all = "kebab-case")
)]
pub enum MediaFeature<'i> {
/// A plain media feature, e.g. `(min-width: 240px)`.
Plain {
/// The name of the feature.
#[cfg_attr(feature = "serde", serde(borrow))]
name: CowArcStr<'i>,
/// The feature value.
value: MediaFeatureValue<'i>,
Expand Down Expand Up @@ -707,6 +734,11 @@ where
///
/// See [MediaFeature](MediaFeature).
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize),
serde(tag = "type", content = "value", rename_all = "kebab-case")
)]
pub enum MediaFeatureValue<'i> {
/// A length value.
Length(Length),
Expand All @@ -717,6 +749,7 @@ pub enum MediaFeatureValue<'i> {
/// A ratio.
Ratio(Ratio),
/// An indentifier.
#[cfg_attr(feature = "serde", serde(borrow))]
Ident(CowArcStr<'i>),
}

Expand Down
6 changes: 3 additions & 3 deletions src/printer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::error::{Error, ErrorLocation, PrinterError, PrinterErrorKind};
use crate::rules::Location;
use crate::targets::Browsers;
use crate::vendor_prefix::VendorPrefix;
use cssparser::{serialize_identifier, SourceLocation};
use cssparser::serialize_identifier;
use parcel_sourcemap::{OriginalLocation, SourceMap};

/// Options that control how CSS is serialized to a string.
Expand Down Expand Up @@ -240,12 +240,12 @@ impl<'a, W: std::fmt::Write + Sized> Printer<'a, W> {
}

/// Returns an error of the given kind at the provided location in the current source file.
pub fn error(&self, kind: PrinterErrorKind, loc: SourceLocation) -> Error<PrinterErrorKind> {
pub fn error(&self, kind: PrinterErrorKind, loc: crate::dependencies::Location) -> Error<PrinterErrorKind> {
Error {
kind,
loc: Some(ErrorLocation {
filename: self.filename().into(),
line: loc.line,
line: loc.line - 1,
column: loc.column,
}),
}
Expand Down
Loading