@@ -153,6 +153,42 @@ impl Color {
153153 }
154154 }
155155
156+ /// Creates a colour from a hex code.
157+ pub fn from_hex < S > ( hex_code : S ) -> Option < Self >
158+ where
159+ S : ToString ,
160+ {
161+ let hex_code = hex_code. to_string ( ) ;
162+ let hex_code = hex_code. trim_start_matches ( "0x" ) ;
163+ let hex_code = hex_code. trim_start_matches ( "#" ) ;
164+ let mut hex_code = hex_code. to_string ( ) ;
165+
166+ // Something like ‘FA0’ gets converted to ‘FFAA00’.
167+ if hex_code. len ( ) == 3 {
168+ let first_character = hex_code. chars ( ) . nth ( 0 ) . unwrap_or ( '0' ) ;
169+ let second_character = hex_code. chars ( ) . nth ( 1 ) . unwrap_or ( '0' ) ;
170+ let third_character = hex_code. chars ( ) . nth ( 2 ) . unwrap_or ( '0' ) ;
171+ hex_code = format ! (
172+ "{}{}{}{}{}{}" ,
173+ first_character,
174+ first_character,
175+ second_character,
176+ second_character,
177+ third_character,
178+ third_character
179+ ) ;
180+ }
181+
182+ if hex_code. len ( ) <= 6 {
183+ let Ok ( value) = u32:: from_str_radix ( & hex_code, 16 ) else {
184+ return None ;
185+ } ;
186+ Some ( Self :: from_rgb_u32 ( value) )
187+ } else {
188+ None
189+ }
190+ }
191+
156192 /// Returns the hue of a colour, in the range 0 to 1.
157193 pub fn hue ( & self ) -> f32 {
158194 let values = vec ! [ self . red, self . green, self . blue] ;
@@ -425,6 +461,54 @@ mod tests {
425461 assert_eq ! ( color. alpha, 0xff ) ;
426462 }
427463
464+ #[ test]
465+ fn from_six_character_hex ( ) {
466+ let color = Color :: from_hex ( "D00DAD" ) ;
467+ let expected_color = Color :: from_rgb_u32 ( 0xd00dad ) ;
468+
469+ assert_eq ! ( color, Some ( expected_color) ) ;
470+ }
471+
472+ #[ test]
473+ fn from_six_character_hex_with_octothorpe ( ) {
474+ let color = Color :: from_hex ( "#D00DAD" ) ;
475+ let expected_color = Color :: from_rgb_u32 ( 0xd00dad ) ;
476+
477+ assert_eq ! ( color, Some ( expected_color) ) ;
478+ }
479+
480+ #[ test]
481+ fn from_three_character_hex ( ) {
482+ let color = Color :: from_hex ( "bed" ) ;
483+ let expected_color = Color :: from_rgb_u32 ( 0xbbeedd ) ;
484+
485+ assert_eq ! ( color, Some ( expected_color) ) ;
486+ }
487+
488+ #[ test]
489+ fn from_four_character_hex ( ) {
490+ let color = Color :: from_hex ( "f00d" ) ;
491+ let expected_color = Color :: from_rgb_u32 ( 0x00f00d ) ;
492+
493+ assert_eq ! ( color, Some ( expected_color) ) ;
494+ }
495+
496+ #[ test]
497+ fn from_five_character_hex ( ) {
498+ let color = Color :: from_hex ( "d000d" ) ;
499+ let expected_color = Color :: from_rgb_u32 ( 0x0d000d ) ;
500+
501+ assert_eq ! ( color, Some ( expected_color) ) ;
502+ }
503+
504+ #[ test]
505+ fn from_two_character_hex ( ) {
506+ let color = Color :: from_hex ( "99" ) ;
507+ let expected_color = Color :: from_rgb_u32 ( 0x000099 ) ;
508+
509+ assert_eq ! ( color, Some ( expected_color) ) ;
510+ }
511+
428512 #[ test]
429513 fn hue ( ) {
430514 let color = Color :: RED ;
0 commit comments