5
5
use std:: fmt;
6
6
use std:: f32:: consts:: PI ;
7
7
8
- use super :: { Token , Parser , ToCss } ;
8
+ use super :: { Token , Parser , ToCss , ParseError } ;
9
9
use tokenizer:: NumericValue ;
10
10
11
11
#[ cfg( feature = "serde" ) ]
@@ -141,46 +141,47 @@ impl Color {
141
141
/// Parse a <color> value, per CSS Color Module Level 3.
142
142
///
143
143
/// FIXME(#2) Deprecated CSS2 System Colors are not supported yet.
144
- pub fn parse ( input : & mut Parser ) -> Result < Color , ( ) > {
145
- match try!( input. next ( ) ) {
146
- Token :: Hash ( value) | Token :: IDHash ( value) => {
144
+ pub fn parse < ' i , ' t > ( input : & mut Parser < ' i , ' t > ) -> Result < Color , ParseError < ' i > > {
145
+ let token = try!( input. next ( ) ) ;
146
+ match token {
147
+ Token :: Hash ( ref value) | Token :: IDHash ( ref value) => {
147
148
Color :: parse_hash ( value. as_bytes ( ) )
148
149
} ,
149
- Token :: Ident ( value) => parse_color_keyword ( & * value) ,
150
- Token :: Function ( name) => {
151
- input. parse_nested_block ( |arguments| {
150
+ Token :: Ident ( ref value) => parse_color_keyword ( & * value) ,
151
+ Token :: Function ( ref name) => {
152
+ return input. parse_nested_block ( |arguments| {
152
153
parse_color_function ( & * name, arguments)
153
- } )
154
+ } ) ;
154
155
}
155
156
_ => Err ( ( ) )
156
- }
157
+ } . map_err ( | ( ) | ParseError :: UnexpectedToken ( token ) )
157
158
}
158
159
159
160
/// Parse a color hash, without the leading '#' character.
160
161
#[ inline]
161
162
pub fn parse_hash ( value : & [ u8 ] ) -> Result < Self , ( ) > {
162
163
match value. len ( ) {
163
- 8 => rgba (
164
+ 8 => Ok ( rgba (
164
165
try!( from_hex ( value[ 0 ] ) ) * 16 + try!( from_hex ( value[ 1 ] ) ) ,
165
166
try!( from_hex ( value[ 2 ] ) ) * 16 + try!( from_hex ( value[ 3 ] ) ) ,
166
167
try!( from_hex ( value[ 4 ] ) ) * 16 + try!( from_hex ( value[ 5 ] ) ) ,
167
- try!( from_hex ( value[ 6 ] ) ) * 16 + try!( from_hex ( value[ 7 ] ) ) ,
168
+ try!( from_hex ( value[ 6 ] ) ) * 16 + try!( from_hex ( value[ 7 ] ) ) ) ,
168
169
) ,
169
- 6 => rgb (
170
+ 6 => Ok ( rgb (
170
171
try!( from_hex ( value[ 0 ] ) ) * 16 + try!( from_hex ( value[ 1 ] ) ) ,
171
172
try!( from_hex ( value[ 2 ] ) ) * 16 + try!( from_hex ( value[ 3 ] ) ) ,
172
- try!( from_hex ( value[ 4 ] ) ) * 16 + try!( from_hex ( value[ 5 ] ) ) ,
173
+ try!( from_hex ( value[ 4 ] ) ) * 16 + try!( from_hex ( value[ 5 ] ) ) ) ,
173
174
) ,
174
- 4 => rgba (
175
+ 4 => Ok ( rgba (
175
176
try!( from_hex ( value[ 0 ] ) ) * 17 ,
176
177
try!( from_hex ( value[ 1 ] ) ) * 17 ,
177
178
try!( from_hex ( value[ 2 ] ) ) * 17 ,
178
- try!( from_hex ( value[ 3 ] ) ) * 17 ,
179
+ try!( from_hex ( value[ 3 ] ) ) * 17 ) ,
179
180
) ,
180
- 3 => rgb (
181
+ 3 => Ok ( rgb (
181
182
try!( from_hex ( value[ 0 ] ) ) * 17 ,
182
183
try!( from_hex ( value[ 1 ] ) ) * 17 ,
183
- try!( from_hex ( value[ 2 ] ) ) * 17 ,
184
+ try!( from_hex ( value[ 2 ] ) ) * 17 ) ,
184
185
) ,
185
186
_ => Err ( ( ) )
186
187
}
@@ -190,13 +191,13 @@ impl Color {
190
191
191
192
192
193
#[ inline]
193
- fn rgb ( red : u8 , green : u8 , blue : u8 ) -> Result < Color , ( ) > {
194
+ fn rgb ( red : u8 , green : u8 , blue : u8 ) -> Color {
194
195
rgba ( red, green, blue, 255 )
195
196
}
196
197
197
198
#[ inline]
198
- fn rgba ( red : u8 , green : u8 , blue : u8 , alpha : u8 ) -> Result < Color , ( ) > {
199
- Ok ( Color :: RGBA ( RGBA :: new ( red, green, blue, alpha) ) )
199
+ fn rgba ( red : u8 , green : u8 , blue : u8 , alpha : u8 ) -> Color {
200
+ Color :: RGBA ( RGBA :: new ( red, green, blue, alpha) )
200
201
}
201
202
202
203
@@ -410,11 +411,11 @@ fn clamp_floor_256_f32(val: f32) -> u8 {
410
411
}
411
412
412
413
#[ inline]
413
- fn parse_color_function ( name : & str , arguments : & mut Parser ) -> Result < Color , ( ) > {
414
+ fn parse_color_function < ' i , ' t > ( name : & str , arguments : & mut Parser < ' i , ' t > ) -> Result < Color , ParseError < ' i > > {
414
415
let ( red, green, blue, uses_commas) = match_ignore_ascii_case ! { name,
415
416
"rgb" | "rgba" => parse_rgb_components_rgb( arguments) ?,
416
417
"hsl" | "hsla" => parse_rgb_components_hsl( arguments) ?,
417
- _ => return Err ( ( ) )
418
+ _ => return Err ( ParseError :: UnexpectedToken ( Token :: Ident ( name . to_owned ( ) . into ( ) ) ) ) ,
418
419
} ;
419
420
420
421
let alpha = if !arguments. is_exhausted ( ) {
@@ -423,7 +424,7 @@ fn parse_color_function(name: &str, arguments: &mut Parser) -> Result<Color, ()>
423
424
} else {
424
425
match try!( arguments. next ( ) ) {
425
426
Token :: Delim ( '/' ) => { } ,
426
- _ => return Err ( ( ) )
427
+ t => return Err ( ParseError :: UnexpectedToken ( t ) ) ,
427
428
} ;
428
429
} ;
429
430
let token = try!( arguments. next ( ) ) ;
@@ -434,21 +435,21 @@ fn parse_color_function(name: &str, arguments: &mut Parser) -> Result<Color, ()>
434
435
Token :: Percentage ( ref v) => {
435
436
clamp_unit_f32 ( v. unit_value )
436
437
}
437
- _ => {
438
- return Err ( ( ) )
438
+ t => {
439
+ return Err ( ParseError :: UnexpectedToken ( t ) )
439
440
}
440
441
}
441
442
} else {
442
443
255
443
444
} ;
444
445
445
446
try!( arguments. expect_exhausted ( ) ) ;
446
- rgba ( red, green, blue, alpha)
447
+ Ok ( rgba ( red, green, blue, alpha) )
447
448
}
448
449
449
450
450
451
#[ inline]
451
- fn parse_rgb_components_rgb ( arguments : & mut Parser ) -> Result < ( u8 , u8 , u8 , bool ) , ( ) > {
452
+ fn parse_rgb_components_rgb < ' i , ' t > ( arguments : & mut Parser < ' i , ' t > ) -> Result < ( u8 , u8 , u8 , bool ) , ParseError < ' i > > {
452
453
let red: u8 ;
453
454
let green: u8 ;
454
455
let blue: u8 ;
@@ -465,7 +466,7 @@ fn parse_rgb_components_rgb(arguments: &mut Parser) -> Result<(u8, u8, u8, bool)
465
466
uses_commas = true ;
466
467
try!( arguments. expect_number ( ) )
467
468
}
468
- _ => return Err ( ( ) )
469
+ t => return Err ( ParseError :: UnexpectedToken ( t ) )
469
470
} ) ;
470
471
if uses_commas {
471
472
try!( arguments. expect_comma ( ) ) ;
@@ -480,36 +481,38 @@ fn parse_rgb_components_rgb(arguments: &mut Parser) -> Result<(u8, u8, u8, bool)
480
481
uses_commas = true ;
481
482
try!( arguments. expect_percentage ( ) )
482
483
}
483
- _ => return Err ( ( ) )
484
+ t => return Err ( ParseError :: UnexpectedToken ( t ) )
484
485
} ) ;
485
486
if uses_commas {
486
487
try!( arguments. expect_comma ( ) ) ;
487
488
}
488
489
blue = clamp_unit_f32 ( try!( arguments. expect_percentage ( ) ) ) ;
489
490
}
490
- _ => return Err ( ( ) )
491
+ t => return Err ( ParseError :: UnexpectedToken ( t ) )
491
492
} ;
492
493
return Ok ( ( red, green, blue, uses_commas) ) ;
493
494
}
494
495
495
496
#[ inline]
496
- fn parse_rgb_components_hsl ( arguments : & mut Parser ) -> Result < ( u8 , u8 , u8 , bool ) , ( ) > {
497
+ fn parse_rgb_components_hsl < ' i , ' t > ( arguments : & mut Parser < ' i , ' t > ) -> Result < ( u8 , u8 , u8 , bool ) , ParseError < ' i > > {
497
498
let mut uses_commas = false ;
498
499
// Hue given as an angle
499
500
// https://drafts.csswg.org/css-values/#angles
500
- let hue_degrees = match try!( arguments. next ( ) ) {
501
- Token :: Number ( NumericValue { value : v, .. } ) => v,
502
- Token :: Dimension ( NumericValue { value : v, .. } , unit) => {
501
+ let token = try!( arguments. next ( ) ) ;
502
+ let hue_degrees = match token {
503
+ Token :: Number ( NumericValue { value : v, .. } ) => Ok ( v) ,
504
+ Token :: Dimension ( NumericValue { value : v, .. } , ref unit) => {
503
505
match_ignore_ascii_case ! { & * unit,
504
- "deg" => v ,
505
- "grad" => v * 360. / 400. ,
506
- "rad" => v * 360. / ( 2. * PI ) ,
507
- "turn" => v * 360. ,
508
- _ => return Err ( ( ) )
506
+ "deg" => Ok ( v ) ,
507
+ "grad" => Ok ( v * 360. / 400. ) ,
508
+ "rad" => Ok ( v * 360. / ( 2. * PI ) ) ,
509
+ "turn" => Ok ( v * 360. ) ,
510
+ _ => Err ( ( ) ) ,
509
511
}
510
512
}
511
- _ => return Err ( ( ) )
513
+ t => return Err ( ParseError :: UnexpectedToken ( t ) )
512
514
} ;
515
+ let hue_degrees = try!( hue_degrees. map_err ( |( ) | ParseError :: UnexpectedToken ( token) ) ) ;
513
516
// Subtract an integer before rounding, to avoid some rounding errors:
514
517
let hue_normalized_degrees = hue_degrees - 360. * ( hue_degrees / 360. ) . floor ( ) ;
515
518
let hue = hue_normalized_degrees / 360. ;
@@ -522,7 +525,7 @@ fn parse_rgb_components_hsl(arguments: &mut Parser) -> Result<(u8, u8, u8, bool)
522
525
uses_commas = true ;
523
526
try!( arguments. expect_percentage ( ) )
524
527
}
525
- _ => return Err ( ( ) )
528
+ t => return Err ( ParseError :: UnexpectedToken ( t ) )
526
529
} ;
527
530
let saturation = saturation. max ( 0. ) . min ( 1. ) ;
528
531
0 commit comments