@@ -287,18 +287,18 @@ impl CssColor {
287287 }
288288
289289 /// Converts the color to RGBA.
290- pub fn to_rgb ( & self ) -> CssColor {
291- RGBA :: from ( self ) . into ( )
290+ pub fn to_rgb ( & self ) -> Result < CssColor , ( ) > {
291+ Ok ( RGBA :: try_from ( self ) ? . into ( ) )
292292 }
293293
294294 /// Converts the color to the LAB color space.
295- pub fn to_lab ( & self ) -> CssColor {
296- LAB :: from ( self ) . into ( )
295+ pub fn to_lab ( & self ) -> Result < CssColor , ( ) > {
296+ Ok ( LAB :: try_from ( self ) ? . into ( ) )
297297 }
298298
299299 /// Converts the color to the P3 color space.
300- pub fn to_p3 ( & self ) -> CssColor {
301- P3 :: from ( self ) . into ( )
300+ pub fn to_p3 ( & self ) -> Result < CssColor , ( ) > {
301+ Ok ( P3 :: try_from ( self ) ? . into ( ) )
302302 }
303303
304304 pub ( crate ) fn get_possible_fallbacks ( & self , targets : Targets ) -> ColorFallbackKind {
@@ -376,9 +376,9 @@ impl CssColor {
376376 }
377377
378378 match kind {
379- ColorFallbackKind :: RGB => self . to_rgb ( ) ,
380- ColorFallbackKind :: P3 => self . to_p3 ( ) ,
381- ColorFallbackKind :: LAB => self . to_lab ( ) ,
379+ ColorFallbackKind :: RGB => self . to_rgb ( ) . unwrap ( ) ,
380+ ColorFallbackKind :: P3 => self . to_p3 ( ) . unwrap ( ) ,
381+ ColorFallbackKind :: LAB => self . to_lab ( ) . unwrap ( ) ,
382382 _ => unreachable ! ( ) ,
383383 }
384384 }
@@ -406,15 +406,15 @@ impl FallbackValues for CssColor {
406406
407407 let mut res = Vec :: new ( ) ;
408408 if fallbacks. contains ( ColorFallbackKind :: RGB ) {
409- res. push ( self . to_rgb ( ) ) ;
409+ res. push ( self . to_rgb ( ) . unwrap ( ) ) ;
410410 }
411411
412412 if fallbacks. contains ( ColorFallbackKind :: P3 ) {
413- res. push ( self . to_p3 ( ) ) ;
413+ res. push ( self . to_p3 ( ) . unwrap ( ) ) ;
414414 }
415415
416416 if fallbacks. contains ( ColorFallbackKind :: LAB ) {
417- * self = self . to_lab ( ) ;
417+ * self = self . to_lab ( ) . unwrap ( ) ;
418418 }
419419
420420 res
@@ -744,12 +744,14 @@ impl ComponentParser {
744744 Self { allow_none, from : None }
745745 }
746746
747- fn parse_relative < ' i , ' t , T : From < CssColor > + ColorSpace > (
747+ fn parse_relative < ' i , ' t , T : TryFrom < CssColor > + ColorSpace > (
748748 & mut self ,
749749 input : & mut Parser < ' i , ' t > ,
750750 ) -> Result < ( ) , ParseError < ' i , ParserError < ' i > > > {
751751 if input. try_parse ( |input| input. expect_ident_matching ( "from" ) ) . is_ok ( ) {
752- let from = T :: from ( CssColor :: parse ( input) ?) . resolve ( ) ;
752+ let from = T :: try_from ( CssColor :: parse ( input) ?)
753+ . map_err ( |_| input. new_custom_error ( ParserError :: InvalidValue ) ) ?
754+ . resolve ( ) ;
753755 self . from = Some ( RelativeComponentParser :: new ( & from) ) ;
754756 }
755757
@@ -895,7 +897,7 @@ fn parse_color_function<'i, 't>(input: &mut Parser<'i, 't>) -> Result<CssColor,
895897
896898/// Parses the lab() and oklab() functions.
897899#[ inline]
898- fn parse_lab < ' i , ' t , T : From < CssColor > + ColorSpace > (
900+ fn parse_lab < ' i , ' t , T : TryFrom < CssColor > + ColorSpace > (
899901 input : & mut Parser < ' i , ' t > ,
900902 parser : & mut ComponentParser ,
901903) -> Result < ( f32 , f32 , f32 , f32 ) , ParseError < ' i , ParserError < ' i > > > {
@@ -917,7 +919,7 @@ fn parse_lab<'i, 't, T: From<CssColor> + ColorSpace>(
917919
918920/// Parses the lch() and oklch() functions.
919921#[ inline]
920- fn parse_lch < ' i , ' t , T : From < CssColor > + ColorSpace > (
922+ fn parse_lch < ' i , ' t , T : TryFrom < CssColor > + ColorSpace > (
921923 input : & mut Parser < ' i , ' t > ,
922924 parser : & mut ComponentParser ,
923925) -> Result < ( f32 , f32 , f32 , f32 ) , ParseError < ' i , ParserError < ' i > > > {
@@ -961,15 +963,16 @@ fn parse_predefined<'i, 't>(
961963 let colorspace = input. expect_ident_cloned ( ) ?;
962964
963965 if let Some ( from) = & from {
966+ let handle_error = |_| input. new_custom_error ( ParserError :: InvalidValue ) ;
964967 parser. from = Some ( match_ignore_ascii_case ! { & * & colorspace,
965- "srgb" => RelativeComponentParser :: new( & SRGB :: from ( from) . resolve_missing( ) ) ,
966- "srgb-linear" => RelativeComponentParser :: new( & SRGBLinear :: from ( from) . resolve_missing( ) ) ,
967- "display-p3" => RelativeComponentParser :: new( & P3 :: from ( from) . resolve_missing( ) ) ,
968- "a98-rgb" => RelativeComponentParser :: new( & A98 :: from ( from) . resolve_missing( ) ) ,
969- "prophoto-rgb" => RelativeComponentParser :: new( & ProPhoto :: from ( from) . resolve_missing( ) ) ,
970- "rec2020" => RelativeComponentParser :: new( & Rec2020 :: from ( from) . resolve_missing( ) ) ,
971- "xyz-d50" => RelativeComponentParser :: new( & XYZd50 :: from ( from) . resolve_missing( ) ) ,
972- "xyz" | "xyz-d65" => RelativeComponentParser :: new( & XYZd65 :: from ( from) . resolve_missing( ) ) ,
968+ "srgb" => RelativeComponentParser :: new( & SRGB :: try_from ( from) . map_err ( handle_error ) ? . resolve_missing( ) ) ,
969+ "srgb-linear" => RelativeComponentParser :: new( & SRGBLinear :: try_from ( from) . map_err ( handle_error ) ? . resolve_missing( ) ) ,
970+ "display-p3" => RelativeComponentParser :: new( & P3 :: try_from ( from) . map_err ( handle_error ) ? . resolve_missing( ) ) ,
971+ "a98-rgb" => RelativeComponentParser :: new( & A98 :: try_from ( from) . map_err ( handle_error ) ? . resolve_missing( ) ) ,
972+ "prophoto-rgb" => RelativeComponentParser :: new( & ProPhoto :: try_from ( from) . map_err ( handle_error ) ? . resolve_missing( ) ) ,
973+ "rec2020" => RelativeComponentParser :: new( & Rec2020 :: try_from ( from) . map_err ( handle_error ) ? . resolve_missing( ) ) ,
974+ "xyz-d50" => RelativeComponentParser :: new( & XYZd50 :: try_from ( from) . map_err ( handle_error ) ? . resolve_missing( ) ) ,
975+ "xyz" | "xyz-d65" => RelativeComponentParser :: new( & XYZd65 :: try_from ( from) . map_err ( handle_error ) ? . resolve_missing( ) ) ,
973976 _ => return Err ( location. new_unexpected_token_error(
974977 cssparser:: Token :: Ident ( colorspace. clone( ) )
975978 ) )
@@ -1013,7 +1016,7 @@ fn parse_predefined<'i, 't>(
10131016/// Only the modern syntax with no commas is handled here, cssparser handles the legacy syntax.
10141017/// The results of this function are stored as floating point if there are any `none` components.
10151018#[ inline]
1016- fn parse_hsl_hwb < ' i , ' t , T : From < CssColor > + ColorSpace > (
1019+ fn parse_hsl_hwb < ' i , ' t , T : TryFrom < CssColor > + ColorSpace > (
10171020 input : & mut Parser < ' i , ' t > ,
10181021 parser : & mut ComponentParser ,
10191022) -> Result < ( f32 , f32 , f32 , f32 ) , ParseError < ' i , ParserError < ' i > > > {
@@ -2575,27 +2578,29 @@ macro_rules! color_space {
25752578 }
25762579 }
25772580
2578- impl From <& CssColor > for $space {
2579- fn from( color: & CssColor ) -> $space {
2580- match color {
2581+ impl TryFrom <& CssColor > for $space {
2582+ type Error = ( ) ;
2583+ fn try_from( color: & CssColor ) -> Result <$space, ( ) > {
2584+ Ok ( match color {
25812585 CssColor :: RGBA ( rgba) => ( * rgba) . into( ) ,
25822586 CssColor :: LAB ( lab) => ( * * lab) . into( ) ,
25832587 CssColor :: Predefined ( predefined) => ( * * predefined) . into( ) ,
25842588 CssColor :: Float ( float) => ( * * float) . into( ) ,
2585- CssColor :: CurrentColor => unreachable! ( ) ,
2586- }
2589+ CssColor :: CurrentColor => return Err ( ( ) ) ,
2590+ } )
25872591 }
25882592 }
25892593
2590- impl From <CssColor > for $space {
2591- fn from( color: CssColor ) -> $space {
2592- match color {
2594+ impl TryFrom <CssColor > for $space {
2595+ type Error = ( ) ;
2596+ fn try_from( color: CssColor ) -> Result <$space, ( ) > {
2597+ Ok ( match color {
25932598 CssColor :: RGBA ( rgba) => rgba. into( ) ,
25942599 CssColor :: LAB ( lab) => ( * lab) . into( ) ,
25952600 CssColor :: Predefined ( predefined) => ( * predefined) . into( ) ,
25962601 CssColor :: Float ( float) => ( * float) . into( ) ,
2597- CssColor :: CurrentColor => unreachable! ( ) ,
2598- }
2602+ CssColor :: CurrentColor => return Err ( ( ) ) ,
2603+ } )
25992604 }
26002605 }
26012606 } ;
@@ -2879,7 +2884,7 @@ fn parse_color_mix<'i, 't>(input: &mut Parser<'i, 't>) -> Result<CssColor, Parse
28792884 return Err ( input. new_custom_error ( ParserError :: InvalidValue ) ) ;
28802885 }
28812886
2882- Ok ( match method {
2887+ match method {
28832888 ColorSpaceName :: SRGB => first_color. interpolate :: < SRGB > ( p1, & second_color, p2, hue_method) ,
28842889 ColorSpaceName :: SRGBLinear => first_color. interpolate :: < SRGBLinear > ( p1, & second_color, p2, hue_method) ,
28852890 ColorSpaceName :: Hsl => first_color. interpolate :: < HSL > ( p1, & second_color, p2, hue_method) ,
@@ -2892,7 +2897,8 @@ fn parse_color_mix<'i, 't>(input: &mut Parser<'i, 't>) -> Result<CssColor, Parse
28922897 first_color. interpolate :: < XYZd65 > ( p1, & second_color, p2, hue_method)
28932898 }
28942899 ColorSpaceName :: XYZd50 => first_color. interpolate :: < XYZd50 > ( p1, & second_color, p2, hue_method) ,
2895- } )
2900+ }
2901+ . map_err ( |_| input. new_custom_error ( ParserError :: InvalidValue ) )
28962902}
28972903
28982904impl CssColor {
@@ -2932,10 +2938,10 @@ impl CssColor {
29322938 other : & ' a CssColor ,
29332939 mut p2 : f32 ,
29342940 method : HueInterpolationMethod ,
2935- ) -> CssColor
2941+ ) -> Result < CssColor , ( ) >
29362942 where
29372943 T : ' static
2938- + From < & ' a CssColor >
2944+ + TryFrom < & ' a CssColor >
29392945 + Interpolate
29402946 + Into < CssColor >
29412947 + Into < OKLCH >
@@ -2944,13 +2950,17 @@ impl CssColor {
29442950 + From < OKLCH >
29452951 + Copy ,
29462952 {
2953+ if matches ! ( self , CssColor :: CurrentColor ) || matches ! ( other, CssColor :: CurrentColor ) {
2954+ return Err ( ( ) ) ;
2955+ }
2956+
29472957 let type_id = TypeId :: of :: < T > ( ) ;
29482958 let converted_first = self . get_type_id ( ) != type_id;
29492959 let converted_second = other. get_type_id ( ) != type_id;
29502960
29512961 // https://drafts.csswg.org/css-color-5/#color-mix-result
2952- let mut first_color = T :: from ( self ) ;
2953- let mut second_color = T :: from ( other) ;
2962+ let mut first_color = T :: try_from ( self ) . map_err ( |_| ( ) ) ? ;
2963+ let mut second_color = T :: try_from ( other) . map_err ( |_| ( ) ) ? ;
29542964
29552965 if converted_first && !first_color. in_gamut ( ) {
29562966 first_color = map_gamut ( first_color) ;
@@ -2993,7 +3003,7 @@ impl CssColor {
29933003 let mut result_color = first_color. interpolate ( p1, & second_color, p2) ;
29943004 result_color. unpremultiply ( alpha_multiplier) ;
29953005
2996- result_color. into ( )
3006+ Ok ( result_color. into ( ) )
29973007 }
29983008}
29993009
0 commit comments