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