Skip to content

Commit

Permalink
Replace TokenSerializationType with TokenSerializationTypeVariants (#369
Browse files Browse the repository at this point in the history
)

* Replace TokenSerializationType with TokenSerializationTypeVariants

Making TokenSerializationType public is useful to describe a CSS string
that is already known to be valid in cases when the
TokenSerializationTypes of the start and end of the CSS string is
needed, but Tokens are not.

This helps with creating a custom_properties::VariableValue from the CSS
string of a computed value for CSS Properties and Values, see Mozilla
bug 1858305 [1].

[1]: https://bugzilla.mozilla.org/show_bug.cgi?id=1858305

* Derive Default trait for TokenSerializationType

* Deprecate TokenSerializationType::nothing()
  • Loading branch information
zrhoffman authored Nov 14, 2023
1 parent cab31ea commit aaa966d
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 50 deletions.
160 changes: 111 additions & 49 deletions src/serializer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -378,19 +378,110 @@ impl_tocss_for_float!(f32);
impl_tocss_for_float!(f64);

/// A category of token. See the `needs_separator_when_before` method.
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub struct TokenSerializationType(TokenSerializationTypeVariants);
#[derive(Copy, Clone, Eq, PartialEq, Debug, Default)]
pub enum TokenSerializationType {
/// No token serialization type.
#[default]
Nothing,

/// The [`<whitespace-token>`](https://drafts.csswg.org/css-syntax/#whitespace-token-diagram)
/// type.
WhiteSpace,

/// The [`<at-keyword-token>`](https://drafts.csswg.org/css-syntax/#at-keyword-token-diagram)
/// type, the "[`<hash-token>`](https://drafts.csswg.org/css-syntax/#hash-token-diagram) with
/// the type flag set to 'unrestricted'" type, or the
/// "[`<hash-token>`](https://drafts.csswg.org/css-syntax/#hash-token-diagram) with the type
/// flag set to 'id'" type.
AtKeywordOrHash,

/// The [`<number-token>`](https://drafts.csswg.org/css-syntax/#number-token-diagram) type.
Number,

/// The [`<dimension-token>`](https://drafts.csswg.org/css-syntax/#dimension-token-diagram)
/// type.
Dimension,

/// The [`<percentage-token>`](https://drafts.csswg.org/css-syntax/#percentage-token-diagram)
/// type.
Percentage,

/// The [`<url-token>`](https://drafts.csswg.org/css-syntax/#url-token-diagram) or
/// `<bad-url-token>` type.
UrlOrBadUrl,

/// The [`<function-token>`](https://drafts.csswg.org/css-syntax/#function-token-diagram) type.
Function,

/// The [`<ident-token>`](https://drafts.csswg.org/css-syntax/#ident-token-diagram) type.
Ident,

/// The `-->` [`<CDC-token>`](https://drafts.csswg.org/css-syntax/#CDC-token-diagram) type.
CDC,

/// The `|=`
/// [`<dash-match-token>`](https://drafts.csswg.org/css-syntax/#dash-match-token-diagram) type.
DashMatch,

/// The `*=`
/// [`<substring-match-token>`](https://drafts.csswg.org/css-syntax/#substring-match-token-diagram)
/// type.
SubstringMatch,

/// The `<(-token>` type.
OpenParen,

/// The `#` `<delim-token>` type.
DelimHash,

/// The `@` `<delim-token>` type.
DelimAt,

/// The `.` or `+` `<delim-token>` type.
DelimDotOrPlus,

/// The `-` `<delim-token>` type.
DelimMinus,

/// The `?` `<delim-token>` type.
DelimQuestion,

/// The `$`, `^`, or `~` `<delim-token>` type.
DelimAssorted,

/// The `=` `<delim-token>` type.
DelimEquals,

/// The `|` `<delim-token>` type.
DelimBar,

/// The `/` `<delim-token>` type.
DelimSlash,

/// The `*` `<delim-token>` type.
DelimAsterisk,

/// The `%` `<delim-token>` type.
DelimPercent,

/// A type indicating any other token.
Other,
}

impl TokenSerializationType {
/// Return a value that represents the absence of a token, e.g. before the start of the input.
#[deprecated(
since = "0.32.1",
note = "use TokenSerializationType::Nothing or TokenSerializationType::default() instead"
)]
pub fn nothing() -> TokenSerializationType {
TokenSerializationType(TokenSerializationTypeVariants::Nothing)
Default::default()
}

/// If this value is `TokenSerializationType::nothing()`, set it to the given value instead.
/// If this value is `TokenSerializationType::Nothing`, set it to the given value instead.
pub fn set_if_nothing(&mut self, new_value: TokenSerializationType) {
if self.0 == TokenSerializationTypeVariants::Nothing {
self.0 = new_value.0
if matches!(self, TokenSerializationType::Nothing) {
*self = new_value
}
}

Expand All @@ -404,10 +495,10 @@ impl TokenSerializationType {
/// See https://github.com/w3c/csswg-drafts/issues/4088 for the
/// `DelimPercent` bits.
pub fn needs_separator_when_before(self, other: TokenSerializationType) -> bool {
use self::TokenSerializationTypeVariants::*;
match self.0 {
use self::TokenSerializationType::*;
match self {
Ident => matches!(
other.0,
other,
Ident
| Function
| UrlOrBadUrl
Expand All @@ -419,15 +510,15 @@ impl TokenSerializationType {
| OpenParen
),
AtKeywordOrHash | Dimension => matches!(
other.0,
other,
Ident | Function | UrlOrBadUrl | DelimMinus | Number | Percentage | Dimension | CDC
),
DelimHash | DelimMinus => matches!(
other.0,
other,
Ident | Function | UrlOrBadUrl | DelimMinus | Number | Percentage | Dimension
),
Number => matches!(
other.0,
other,
Ident
| Function
| UrlOrBadUrl
Expand All @@ -437,11 +528,11 @@ impl TokenSerializationType {
| DelimPercent
| Dimension
),
DelimAt => matches!(other.0, Ident | Function | UrlOrBadUrl | DelimMinus),
DelimDotOrPlus => matches!(other.0, Number | Percentage | Dimension),
DelimAssorted | DelimAsterisk => matches!(other.0, DelimEquals),
DelimBar => matches!(other.0, DelimEquals | DelimBar | DashMatch),
DelimSlash => matches!(other.0, DelimAsterisk | SubstringMatch),
DelimAt => matches!(other, Ident | Function | UrlOrBadUrl | DelimMinus),
DelimDotOrPlus => matches!(other, Number | Percentage | Dimension),
DelimAssorted | DelimAsterisk => matches!(other, DelimEquals),
DelimBar => matches!(other, DelimEquals | DelimBar | DashMatch),
DelimSlash => matches!(other, DelimAsterisk | SubstringMatch),
Nothing | WhiteSpace | Percentage | UrlOrBadUrl | Function | CDC | OpenParen
| DashMatch | SubstringMatch | DelimQuestion | DelimEquals | DelimPercent | Other => {
false
Expand All @@ -450,43 +541,14 @@ impl TokenSerializationType {
}
}

#[derive(Copy, Clone, Eq, PartialEq, Debug)]
enum TokenSerializationTypeVariants {
Nothing,
WhiteSpace,
AtKeywordOrHash,
Number,
Dimension,
Percentage,
UrlOrBadUrl,
Function,
Ident,
CDC,
DashMatch,
SubstringMatch,
OpenParen, // '('
DelimHash, // '#'
DelimAt, // '@'
DelimDotOrPlus, // '.', '+'
DelimMinus, // '-'
DelimQuestion, // '?'
DelimAssorted, // '$', '^', '~'
DelimEquals, // '='
DelimBar, // '|'
DelimSlash, // '/'
DelimAsterisk, // '*'
DelimPercent, // '%'
Other, // anything else
}

impl<'a> Token<'a> {
/// Categorize a token into a type that determines when `/**/` needs to be inserted
/// between two tokens when serialized next to each other without whitespace in between.
///
/// See the `TokenSerializationType::needs_separator_when_before` method.
pub fn serialization_type(&self) -> TokenSerializationType {
use self::TokenSerializationTypeVariants::*;
TokenSerializationType(match *self {
use self::TokenSerializationType::*;
match self {
Token::Ident(_) => Ident,
Token::AtKeyword(_) | Token::Hash(_) | Token::IDHash(_) => AtKeywordOrHash,
Token::UnquotedUrl(_) | Token::BadUrl(_) => UrlOrBadUrl,
Expand Down Expand Up @@ -526,6 +588,6 @@ impl<'a> Token<'a> {
| Token::IncludeMatch
| Token::PrefixMatch
| Token::SuffixMatch => Other,
})
}
}
}
2 changes: 1 addition & 1 deletion src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ fn serializer(preserve_comments: bool) {
}
let mut serialized = String::new();
write_to(
TokenSerializationType::nothing(),
TokenSerializationType::Nothing,
input,
&mut serialized,
preserve_comments,
Expand Down

0 comments on commit aaa966d

Please sign in to comment.