Skip to content

Commit 1b8dcea

Browse files
committed
Make parse error types extensible.
1 parent f51e0dd commit 1b8dcea

File tree

7 files changed

+239
-166
lines changed

7 files changed

+239
-166
lines changed

src/color.rs

+17-16
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use std::fmt;
66
use std::f32::consts::PI;
77

8-
use super::{Token, Parser, ToCss, ParseError};
8+
use super::{Token, Parser, ToCss, ParseError, BasicParseError};
99
use tokenizer::NumericValue;
1010

1111
#[cfg(feature = "serde")]
@@ -141,18 +141,19 @@ impl Color {
141141
/// Parse a <color> value, per CSS Color Module Level 3.
142142
///
143143
/// FIXME(#2) Deprecated CSS2 System Colors are not supported yet.
144-
pub fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Color, ParseError<'i>> {
144+
pub fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Color, BasicParseError<'i>> {
145145
let token = try!(input.next());
146146
match token {
147147
Token::Hash(ref value) | Token::IDHash(ref value) => parse_color_hash(&*value),
148148
Token::Ident(ref value) => parse_color_keyword(&*value),
149149
Token::Function(ref name) => {
150150
return input.parse_nested_block(|arguments| {
151151
parse_color_function(&*name, arguments)
152-
});
152+
.map_err(|e| ParseError::Basic(e))
153+
}).map_err(ParseError::<()>::basic);
153154
}
154155
_ => Err(())
155-
}.map_err(|()| ParseError::UnexpectedToken(token))
156+
}.map_err(|()| BasicParseError::UnexpectedToken(token))
156157
}
157158
}
158159

@@ -402,11 +403,11 @@ fn clamp_256_f32(val: f32) -> u8 {
402403
}
403404

404405
#[inline]
405-
fn parse_color_function<'i, 't>(name: &str, arguments: &mut Parser<'i, 't>) -> Result<Color, ParseError<'i>> {
406+
fn parse_color_function<'i, 't>(name: &str, arguments: &mut Parser<'i, 't>) -> Result<Color, BasicParseError<'i>> {
406407
let (red, green, blue, uses_commas) = match_ignore_ascii_case! { name,
407408
"rgb" | "rgba" => parse_rgb_components_rgb(arguments)?,
408409
"hsl" | "hsla" => parse_rgb_components_hsl(arguments)?,
409-
_ => return Err(ParseError::UnexpectedToken(Token::Ident(name.to_owned().into()))),
410+
_ => return Err(BasicParseError::UnexpectedToken(Token::Ident(name.to_owned().into()))),
410411
};
411412

412413
let alpha = if !arguments.is_exhausted() {
@@ -415,7 +416,7 @@ fn parse_color_function<'i, 't>(name: &str, arguments: &mut Parser<'i, 't>) -> R
415416
} else {
416417
match try!(arguments.next()) {
417418
Token::Delim('/') => {},
418-
t => return Err(ParseError::UnexpectedToken(t)),
419+
t => return Err(BasicParseError::UnexpectedToken(t)),
419420
};
420421
};
421422
let token = try!(arguments.next());
@@ -427,7 +428,7 @@ fn parse_color_function<'i, 't>(name: &str, arguments: &mut Parser<'i, 't>) -> R
427428
clamp_unit_f32(v.unit_value)
428429
}
429430
t => {
430-
return Err(ParseError::UnexpectedToken(t))
431+
return Err(BasicParseError::UnexpectedToken(t))
431432
}
432433
}
433434
} else {
@@ -440,7 +441,7 @@ fn parse_color_function<'i, 't>(name: &str, arguments: &mut Parser<'i, 't>) -> R
440441

441442

442443
#[inline]
443-
fn parse_rgb_components_rgb<'i, 't>(arguments: &mut Parser<'i, 't>) -> Result<(u8, u8, u8, bool), ParseError<'i>> {
444+
fn parse_rgb_components_rgb<'i, 't>(arguments: &mut Parser<'i, 't>) -> Result<(u8, u8, u8, bool), BasicParseError<'i>> {
444445
let red: u8;
445446
let green: u8;
446447
let blue: u8;
@@ -457,7 +458,7 @@ fn parse_rgb_components_rgb<'i, 't>(arguments: &mut Parser<'i, 't>) -> Result<(u
457458
uses_commas = true;
458459
try!(arguments.expect_number())
459460
}
460-
t => return Err(ParseError::UnexpectedToken(t))
461+
t => return Err(BasicParseError::UnexpectedToken(t))
461462
});
462463
if uses_commas {
463464
try!(arguments.expect_comma());
@@ -472,20 +473,20 @@ fn parse_rgb_components_rgb<'i, 't>(arguments: &mut Parser<'i, 't>) -> Result<(u
472473
uses_commas = true;
473474
try!(arguments.expect_percentage())
474475
}
475-
t => return Err(ParseError::UnexpectedToken(t))
476+
t => return Err(BasicParseError::UnexpectedToken(t))
476477
});
477478
if uses_commas {
478479
try!(arguments.expect_comma());
479480
}
480481
blue = clamp_unit_f32(try!(arguments.expect_percentage()));
481482
}
482-
t => return Err(ParseError::UnexpectedToken(t))
483+
t => return Err(BasicParseError::UnexpectedToken(t))
483484
};
484485
return Ok((red, green, blue, uses_commas));
485486
}
486487

487488
#[inline]
488-
fn parse_rgb_components_hsl<'i, 't>(arguments: &mut Parser<'i, 't>) -> Result<(u8, u8, u8, bool), ParseError<'i>> {
489+
fn parse_rgb_components_hsl<'i, 't>(arguments: &mut Parser<'i, 't>) -> Result<(u8, u8, u8, bool), BasicParseError<'i>> {
489490
let mut uses_commas = false;
490491
// Hue given as an angle
491492
// https://drafts.csswg.org/css-values/#angles
@@ -501,9 +502,9 @@ fn parse_rgb_components_hsl<'i, 't>(arguments: &mut Parser<'i, 't>) -> Result<(u
501502
_ => Err(()),
502503
}
503504
}
504-
t => return Err(ParseError::UnexpectedToken(t))
505+
t => return Err(BasicParseError::UnexpectedToken(t))
505506
};
506-
let hue_degrees = try!(hue_degrees.map_err(|()| ParseError::UnexpectedToken(token)));
507+
let hue_degrees = try!(hue_degrees.map_err(|()| BasicParseError::UnexpectedToken(token)));
507508
// Subtract an integer before rounding, to avoid some rounding errors:
508509
let hue_normalized_degrees = hue_degrees - 360. * (hue_degrees / 360.).floor();
509510
let hue = hue_normalized_degrees / 360.;
@@ -516,7 +517,7 @@ fn parse_rgb_components_hsl<'i, 't>(arguments: &mut Parser<'i, 't>) -> Result<(u
516517
uses_commas = true;
517518
try!(arguments.expect_percentage())
518519
}
519-
t => return Err(ParseError::UnexpectedToken(t))
520+
t => return Err(BasicParseError::UnexpectedToken(t))
520521
};
521522
let saturation = saturation.max(0.).min(1.);
522523

src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ pub use from_bytes::{stylesheet_encoding, EncodingSupport};
8989
pub use color::{RGBA, Color, parse_color_keyword};
9090
pub use nth::parse_nth;
9191
pub use serializer::{ToCss, CssStringWriter, serialize_identifier, serialize_string, TokenSerializationType};
92-
pub use parser::{Parser, Delimiter, Delimiters, SourcePosition, ParseError};
92+
pub use parser::{Parser, Delimiter, Delimiters, SourcePosition, ParseError, BasicParseError};
9393
pub use unicode_range::UnicodeRange;
9494

9595
// For macros

src/nth.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44

55
use std::ascii::AsciiExt;
66

7-
use super::{Token, Parser, ParseError};
7+
use super::{Token, Parser, BasicParseError};
88

99

1010
/// Parse the *An+B* notation, as found in the `:nth-child()` selector.
1111
/// The input is typically the arguments of a function,
1212
/// in which case the caller needs to check if the arguments’ parser is exhausted.
1313
/// Return `Ok((A, B))`, or `Err(())` for a syntax error.
14-
pub fn parse_nth<'i, 't>(input: &mut Parser<'i, 't>) -> Result<(i32, i32), ParseError<'i>> {
14+
pub fn parse_nth<'i, 't>(input: &mut Parser<'i, 't>) -> Result<(i32, i32), BasicParseError<'i>> {
1515
let token = try!(input.next());
1616
match token {
1717
Token::Number(ref value) => {
@@ -59,14 +59,14 @@ pub fn parse_nth<'i, 't>(input: &mut Parser<'i, 't>) -> Result<(i32, i32), Parse
5959
_ => parse_n_dash_digits(&*value).map(|v| (1, v))
6060
}
6161
}
62-
t => return Err(ParseError::UnexpectedToken(t)),
62+
t => return Err(BasicParseError::UnexpectedToken(t)),
6363
},
6464
_ => Err(()),
65-
}.map_err(|()| ParseError::UnexpectedToken(token))
65+
}.map_err(|()| BasicParseError::UnexpectedToken(token))
6666
}
6767

6868

69-
fn parse_b<'i, 't>(input: &mut Parser<'i, 't>, a: i32) -> Result<(i32, i32), ParseError<'i>> {
69+
fn parse_b<'i, 't>(input: &mut Parser<'i, 't>, a: i32) -> Result<(i32, i32), BasicParseError<'i>> {
7070
let start_position = input.position();
7171
let token = input.next();
7272
match token {
@@ -82,10 +82,10 @@ fn parse_b<'i, 't>(input: &mut Parser<'i, 't>, a: i32) -> Result<(i32, i32), Par
8282
input.reset(start_position);
8383
Ok((a, 0))
8484
}
85-
}.map_err(|()| ParseError::UnexpectedToken(token.unwrap()))
85+
}.map_err(|()| BasicParseError::UnexpectedToken(token.unwrap()))
8686
}
8787

88-
fn parse_signless_b<'i, 't>(input: &mut Parser<'i, 't>, a: i32, b_sign: i32) -> Result<(i32, i32), ParseError<'i>> {
88+
fn parse_signless_b<'i, 't>(input: &mut Parser<'i, 't>, a: i32, b_sign: i32) -> Result<(i32, i32), BasicParseError<'i>> {
8989
let token = try!(input.next());
9090
match token {
9191
Token::Number(ref value) if !value.has_sign => {
@@ -95,7 +95,7 @@ fn parse_signless_b<'i, 't>(input: &mut Parser<'i, 't>, a: i32, b_sign: i32) ->
9595
}
9696
}
9797
_ => Err(())
98-
}.map_err(|()| ParseError::UnexpectedToken(token))
98+
}.map_err(|()| BasicParseError::UnexpectedToken(token))
9999
}
100100

101101
fn parse_n_dash_digits(string: &str) -> Result<i32, ()> {

0 commit comments

Comments
 (0)