1mod angle;
2mod hsl;
3mod ratio;
4mod rgb;
5
6pub use angle::*;
7pub use hsl::*;
8pub use ratio::*;
9pub use rgb::*;
10
11pub trait Color {
14 type Alpha: Color;
15
16 fn to_css(self) -> String;
29
30 fn to_rgb(self) -> RGB;
43
44 fn to_rgba(self) -> RGBA;
57
58 fn to_hsl(self) -> HSL;
73
74 fn to_hsla(self) -> HSLA;
89
90 fn saturate(self, amount: Ratio) -> Self;
105
106 fn desaturate(self, amount: Ratio) -> Self;
121
122 fn lighten(self, amount: Ratio) -> Self;
137
138 fn darken(self, amount: Ratio) -> Self;
153
154 fn fadein(self, amount: Ratio) -> Self::Alpha;
169
170 fn fadeout(self, amount: Ratio) -> Self::Alpha;
185
186 fn fade(self, amount: Ratio) -> Self::Alpha;
201
202 fn spin(self, amount: Angle) -> Self;
217
218 fn mix<T: Color>(self, other: T, weight: Ratio) -> Self::Alpha;
234
235 fn tint(self, weight: Ratio) -> Self;
250
251 fn shade(self, weight: Ratio) -> Self;
266
267 fn greyscale(self) -> Self;
282}
283
284#[cfg(test)]
285mod css_color_tests {
286 use angle::*;
287 use ratio::*;
288 use {hsl, hsla, rgb, rgba, Angle, Color, Ratio, HSL, HSLA, RGB, RGBA};
289
290 pub trait ApproximatelyEq {
291 fn approximately_eq(self, other: Self) -> bool;
292 }
293
294 impl ApproximatelyEq for u8 {
295 fn approximately_eq(self, other: Self) -> bool {
296 self == other || self + 1 == other || self - 1 == other
297 }
298 }
299
300 impl ApproximatelyEq for u16 {
301 fn approximately_eq(self, other: Self) -> bool {
302 self == other || self + 1 == other || self - 1 == other
303 }
304 }
305
306 impl ApproximatelyEq for Angle {
307 fn approximately_eq(self, other: Self) -> bool {
308 self.degrees().approximately_eq(other.degrees())
309 }
310 }
311
312 impl ApproximatelyEq for Ratio {
313 fn approximately_eq(self, other: Self) -> bool {
314 self.as_u8().approximately_eq(other.as_u8())
315 }
316 }
317
318 impl ApproximatelyEq for RGB {
319 fn approximately_eq(self, other: Self) -> bool {
320 self.to_css() == other.to_css()
321 || self.r.approximately_eq(other.r)
322 && self.g.approximately_eq(other.g)
323 && self.b.approximately_eq(other.b)
324 }
325 }
326
327 impl ApproximatelyEq for RGBA {
328 fn approximately_eq(self, other: Self) -> bool {
329 self.to_css() == other.to_css()
330 || self.r.approximately_eq(other.r)
331 && self.g.approximately_eq(other.g)
332 && self.b.approximately_eq(other.b)
333 && self.a == other.a
334 }
335 }
336
337 impl ApproximatelyEq for HSL {
338 fn approximately_eq(self, other: Self) -> bool {
339 self.to_css() == other.to_css()
340 || self.h.approximately_eq(other.h)
341 && self
342 .s
343 .as_percentage()
344 .approximately_eq(other.s.as_percentage())
345 && self
346 .l
347 .as_percentage()
348 .approximately_eq(other.l.as_percentage())
349 }
350 }
351
352 impl ApproximatelyEq for HSLA {
353 fn approximately_eq(self, other: Self) -> bool {
354 self.to_css() == other.to_css()
355 || self.h.approximately_eq(other.h)
356 && self
357 .s
358 .as_percentage()
359 .approximately_eq(other.s.as_percentage())
360 && self
361 .l
362 .as_percentage()
363 .approximately_eq(other.l.as_percentage())
364 && self.a == other.a
365 }
366 }
367
368 #[macro_export]
369 macro_rules! assert_approximately_eq {
370 ($lhs:expr, $rhs:expr) => {
371 let lhs = $lhs;
372 let rhs = $rhs;
373
374 assert!(lhs.approximately_eq(rhs), "lhs: {}, rhs: {}", lhs, rhs);
375 };
376 }
377
378 #[test]
379 fn can_create_color_structs() {
380 assert_eq!(
381 rgb(5, 10, 15),
382 RGB {
383 r: Ratio::from_u8(5),
384 g: Ratio::from_u8(10),
385 b: Ratio::from_u8(15),
386 }
387 );
388 assert_eq!(
389 rgba(5, 10, 15, 1.0),
390 RGBA {
391 r: Ratio::from_u8(5),
392 g: Ratio::from_u8(10),
393 b: Ratio::from_u8(15),
394 a: Ratio::from_u8(255),
395 }
396 );
397 assert_eq!(
398 hsl(6, 93, 71),
399 HSL {
400 h: Angle::new(6),
401 s: Ratio::from_percentage(93),
402 l: Ratio::from_percentage(71)
403 }
404 );
405 assert_eq!(
406 hsla(6, 93, 71, 1.0),
407 HSLA {
408 h: Angle::new(6),
409 s: Ratio::from_percentage(93),
410 l: Ratio::from_percentage(71),
411 a: Ratio::from_u8(255),
412 }
413 );
414 }
415
416 #[macro_use]
417 mod conversions {
418 macro_rules! conversion_test {
419 (
420 $color_name:ident,
421 rgb($r:expr, $g:expr, $b:expr),
422 hsl($h:expr, $s:expr, $l:expr)
423 ) => {
424 mod $color_name {
425 use super::super::ApproximatelyEq;
426 use $crate::{hsl, hsla, rgb, rgba, Color};
427
428 #[test]
429 fn rgb_to_rgb() {
430 assert_eq!(rgb($r, $g, $b).to_rgb(), rgb($r, $g, $b));
431 }
432
433 #[test]
434 fn rgb_to_rgba() {
435 assert_eq!(rgb($r, $g, $b).to_rgba(), rgba($r, $g, $b, 1.0));
436 }
437
438 #[test]
439 fn rgba_to_rgb() {
440 assert_eq!(rgba($r, $g, $b, 1.0).to_rgb(), rgb($r, $g, $b));
441 assert_eq!(rgba($r, $g, $b, 0.78).to_rgb(), rgb($r, $g, $b));
442 assert_eq!(rgba($r, $g, $b, 0.0).to_rgb(), rgb($r, $g, $b));
443 }
444
445 #[test]
446 fn rgba_to_rgba() {
447 assert_eq!(rgba($r, $g, $b, 1.0).to_rgba(), rgba($r, $g, $b, 1.0));
448
449 assert_eq!(rgba($r, $g, $b, 0.78).to_rgba(), rgba($r, $g, $b, 0.78));
450
451 assert_eq!(rgba($r, $g, $b, 0.0).to_rgba(), rgba($r, $g, $b, 0.0));
452 }
453
454 #[test]
455 fn rgb_to_hsl() {
456 assert_approximately_eq!(rgb($r, $g, $b).to_hsl(), hsl($h, $s, $l));
457 }
458
459 #[test]
460 fn rgb_to_hsla() {
461 assert_approximately_eq!(rgb($r, $g, $b).to_hsla(), hsla($h, $s, $l, 1.0));
462 }
463
464 #[test]
465 fn rgba_to_hsl() {
466 assert_approximately_eq!(rgba($r, $g, $b, 1.0).to_hsl(), hsl($h, $s, $l));
467
468 assert_approximately_eq!(rgba($r, $g, $b, 0.78).to_hsl(), hsl($h, $s, $l));
469
470 assert_approximately_eq!(rgba($r, $g, $b, 0.0).to_hsl(), hsl($h, $s, $l));
471 }
472
473 #[test]
474 fn rgba_to_hsla() {
475 assert_approximately_eq!(
476 rgba($r, $g, $b, 1.0).to_hsla(),
477 hsla($h, $s, $l, 1.0)
478 );
479
480 assert_approximately_eq!(
481 rgba($r, $g, $b, 0.78).to_hsla(),
482 hsla($h, $s, $l, 0.78)
483 );
484
485 assert_approximately_eq!(
486 rgba($r, $g, $b, 0.0).to_hsla(),
487 hsla($h, $s, $l, 0.0)
488 );
489 }
490
491 #[test]
492 fn hsl_to_hsl() {
493 assert_eq!(hsl($h, $s, $l).to_hsl(), hsl($h, $s, $l));
494 }
495
496 #[test]
497 fn hsl_to_hsla() {
498 assert_eq!(hsl($h, $s, $l).to_hsla(), hsla($h, $s, $l, 1.0));
499 }
500
501 #[test]
502 fn hsla_to_hsl() {
503 assert_eq!(hsla($h, $s, $l, 1.0).to_hsl(), hsl($h, $s, $l));
504
505 assert_eq!(hsla($h, $s, $l, 0.78).to_hsl(), hsl($h, $s, $l));
506
507 assert_eq!(hsla($h, $s, $l, 0.0).to_hsl(), hsl($h, $s, $l));
508 }
509
510 #[test]
511 fn hsla_to_hsla() {
512 assert_eq!(hsla($h, $s, $l, 1.0).to_hsla(), hsla($h, $s, $l, 1.0));
513
514 assert_eq!(hsla($h, $s, $l, 0.78).to_hsla(), hsla($h, $s, $l, 0.78));
515
516 assert_eq!(hsla($h, $s, $l, 0.0).to_hsla(), hsla($h, $s, $l, 0.0));
517 }
518
519 #[test]
520 fn hsl_to_rgb() {
521 assert_approximately_eq!(hsl($h, $s, $l).to_rgb(), rgb($r, $g, $b));
522 }
523
524 #[test]
525 fn hsl_to_rgba() {
526 assert_approximately_eq!(hsl($h, $s, $l).to_rgba(), rgba($r, $g, $b, 1.0));
527 }
528
529 #[test]
530 fn hsla_to_rgb() {
531 assert_approximately_eq!(hsla($h, $s, $l, 1.0).to_rgb(), rgb($r, $g, $b));
532
533 assert_approximately_eq!(hsla($h, $s, $l, 0.78).to_rgb(), rgb($r, $g, $b));
534
535 assert_approximately_eq!(hsla($h, $s, $l, 0.0).to_rgb(), rgb($r, $g, $b));
536 }
537
538 #[test]
539 fn hsla_to_rgba() {
540 assert_approximately_eq!(
541 hsla($h, $s, $l, 1.0).to_rgba(),
542 rgba($r, $g, $b, 1.0)
543 );
544
545 assert_approximately_eq!(
546 hsla($h, $s, $l, 0.78).to_rgba(),
547 rgba($r, $g, $b, 0.78)
548 );
549
550 assert_approximately_eq!(
551 hsla($h, $s, $l, 0.0).to_rgba(),
552 rgba($r, $g, $b, 0.0)
553 );
554 }
555 }
556 };
557 }
558
559 conversion_test!(black, rgb(0, 0, 0), hsl(0, 0, 0));
560 conversion_test!(grey, rgb(230, 230, 230), hsl(0, 0, 90));
561 conversion_test!(white, rgb(255, 255, 255), hsl(0, 0, 100));
562 conversion_test!(pink, rgb(253, 216, 229), hsl(339, 90, 92));
563 conversion_test!(brown, rgb(172, 96, 83), hsl(9, 35, 50));
564 conversion_test!(teal, rgb(23, 98, 119), hsl(193, 68, 28));
565 conversion_test!(green, rgb(89, 161, 54), hsl(100, 50, 42));
566 conversion_test!(pale_blue, rgb(148, 189, 209), hsl(200, 40, 70));
567 conversion_test!(mauve, rgb(136, 102, 153), hsl(280, 20, 50));
568 conversion_test!(cherry, rgb(230, 25, 60), hsl(350, 80, 50));
569 conversion_test!(tomato, rgb(255, 99, 71), hsl(9, 100, 64));
570 conversion_test!(light_salmon, rgb(255, 160, 122), hsl(17, 100, 74));
571 conversion_test!(blue_violet, rgb(138, 43, 226), hsl(271, 76, 53));
572 conversion_test!(dark_orange, rgb(255, 140, 0), hsl(33, 100, 50));
573 conversion_test!(deep_pink, rgb(255, 20, 147), hsl(328, 100, 54));
574 conversion_test!(chartreuse, rgb(127, 255, 0), hsl(90, 100, 50));
575 }
576
577 #[test]
578 fn can_saturate() {
579 assert_approximately_eq!(hsl(9, 35, 50).saturate(percent(20)), hsl(9, 55, 50));
580 assert_approximately_eq!(
581 hsla(9, 35, 50, 1.0).saturate(percent(20)),
582 hsla(9, 55, 50, 1.0)
583 );
584
585 assert_approximately_eq!(rgb(172, 96, 83).saturate(percent(20)), rgb(197, 78, 57));
586 assert_approximately_eq!(
587 rgba(172, 96, 83, 1.0).saturate(percent(20)),
588 rgba(197, 78, 57, 1.0)
589 );
590 }
591
592 #[test]
593 fn can_desaturate() {
594 assert_approximately_eq!(hsl(9, 55, 50).desaturate(percent(20)), hsl(9, 35, 50));
595 assert_approximately_eq!(
596 hsla(9, 55, 50, 1.0).desaturate(percent(20)),
597 hsla(9, 35, 50, 1.0)
598 );
599 assert_approximately_eq!(rgb(197, 78, 57).desaturate(percent(20)), rgb(172, 96, 83));
600 assert_approximately_eq!(
601 rgba(197, 78, 57, 1.0).desaturate(percent(20)),
602 rgba(172, 96, 83, 1.0)
603 );
604 }
605
606 #[test]
607 fn can_lighten() {
608 assert_approximately_eq!(hsl(9, 35, 50).lighten(percent(20)), hsl(9, 35, 70));
609 assert_approximately_eq!(
610 hsla(9, 35, 50, 1.0).lighten(percent(20)),
611 hsla(9, 35, 70, 1.0)
612 );
613 assert_approximately_eq!(rgb(172, 96, 83).lighten(percent(20)), rgb(205, 160, 152));
614 assert_approximately_eq!(
615 rgba(172, 96, 83, 1.0).lighten(percent(20)),
616 rgba(205, 160, 152, 1.0)
617 );
618 }
619
620 #[test]
621 fn can_darken() {
622 assert_approximately_eq!(hsl(9, 35, 70).darken(percent(20)), hsl(9, 35, 50));
623 assert_approximately_eq!(
624 hsla(9, 35, 70, 1.0).darken(percent(20)),
625 hsla(9, 35, 50, 1.0)
626 );
627 assert_approximately_eq!(rgb(205, 160, 152).darken(percent(20)), rgb(172, 96, 83));
628 assert_approximately_eq!(
629 rgba(205, 160, 152, 1.0).darken(percent(20)),
630 rgba(172, 96, 83, 1.0)
631 );
632 }
633
634 #[test]
635 fn can_fadein() {
636 assert_approximately_eq!(hsl(9, 35, 50).fadein(percent(25)), hsla(9, 35, 50, 1.0));
637 assert_approximately_eq!(
638 hsla(9, 35, 50, 0.5).fadein(percent(25)),
639 hsla(9, 35, 50, 0.75)
640 );
641 assert_approximately_eq!(rgb(172, 96, 83).fadein(percent(25)), rgba(172, 96, 83, 1.0));
642 assert_approximately_eq!(
643 rgba(172, 96, 83, 0.50).fadein(percent(25)),
644 rgba(172, 96, 83, 0.75)
645 );
646 }
647
648 #[test]
649 fn can_fadeout() {
650 assert_approximately_eq!(hsl(9, 35, 50).fadeout(percent(25)), hsla(9, 35, 50, 0.75));
651 assert_approximately_eq!(
652 rgb(172, 96, 83).fadeout(percent(25)),
653 rgba(172, 96, 83, 0.75)
654 );
655 assert_approximately_eq!(
656 hsla(9, 35, 50, 0.60).fadeout(percent(25)),
657 hsla(9, 35, 50, 0.35)
658 );
659 assert_approximately_eq!(
660 rgba(172, 96, 83, 0.60).fadeout(percent(25)),
661 rgba(172, 96, 83, 0.35)
662 );
663 }
664
665 #[test]
666 fn can_fade() {
667 let faded_color = rgba(23, 98, 119, 0.5);
668
669 assert_approximately_eq!(rgb(23, 98, 119).fade(percent(50)), faded_color);
670 assert_approximately_eq!(rgba(23, 98, 119, 1.0).fade(percent(50)), faded_color);
671 assert_approximately_eq!(hsl(193, 67, 28).fade(percent(50)), faded_color.to_hsla());
672 assert_approximately_eq!(
673 hsla(193, 67, 28, 1.0).fade(percent(50)),
674 faded_color.to_hsla()
675 );
676 }
677
678 #[test]
679 fn can_spin_forward() {
680 assert_approximately_eq!(rgb(75, 207, 23).spin(deg(100)), rgb(23, 136, 207));
681 assert_approximately_eq!(
682 rgba(75, 207, 23, 1.0).spin(deg(100)),
683 rgba(23, 136, 207, 1.0)
684 );
685 assert_approximately_eq!(hsl(10, 90, 50).spin(deg(30)), hsl(40, 90, 50));
686 assert_approximately_eq!(hsla(10, 90, 50, 1.0).spin(deg(30)), hsla(40, 90, 50, 1.0));
687 }
688
689 #[test]
690 fn can_spin_backwards() {
691 assert_approximately_eq!(rgb(75, 207, 23).spin(deg(-100)), rgb(207, 32, 23));
692 assert_approximately_eq!(
693 rgba(75, 207, 23, 1.0).spin(deg(-100)),
694 rgba(207, 32, 23, 1.0)
695 );
696 assert_approximately_eq!(hsl(10, 90, 50).spin(deg(-30)), hsl(340, 90, 50));
697 assert_approximately_eq!(hsla(10, 90, 50, 1.0).spin(deg(-30)), hsla(340, 90, 50, 1.0));
698 }
699
700 #[test]
701 fn can_mix() {
702 let brown_rgba = rgba(50, 50, 0, 1.0);
703 let brown_hsla = hsla(60, 100, 10, 1.0);
704
705 assert_approximately_eq!(
706 rgba(100, 0, 0, 1.0).mix(rgba(0, 100, 0, 1.0), percent(50)),
707 brown_rgba
708 );
709 assert_approximately_eq!(rgb(100, 0, 0).mix(rgb(0, 100, 0), percent(50)), brown_rgba);
710 assert_approximately_eq!(
711 hsl(0, 100, 20).mix(hsl(120, 100, 20), percent(50)),
712 brown_hsla
713 );
714 assert_approximately_eq!(
715 hsla(0, 100, 20, 1.0).mix(hsla(120, 100, 20, 1.0), percent(50)),
716 brown_hsla
717 );
718 }
719
720 #[test]
721 fn can_mix_single_color() {
722 let rgba_red = rgba(100, 0, 0, 1.0);
723 let rgba_green = rgba(0, 100, 0, 0.5);
724 let hsla_red = hsla(120, 100, 20, 1.0);
725 let hsla_green = hsla(0, 100, 20, 0.5);
726
727 assert_approximately_eq!(rgba_red.mix(rgba_green, percent(100)), rgba_red);
728 assert_approximately_eq!(rgba_red.mix(rgba_green, percent(0)), rgba_green);
729 assert_approximately_eq!(rgba_green.mix(rgba_red, percent(100)), rgba_green);
730 assert_approximately_eq!(rgba_green.mix(rgba_red, percent(0)), rgba_red);
731 assert_approximately_eq!(rgba_red.mix(rgba_green, percent(0)), rgba_green);
732
733 assert_approximately_eq!(hsla_red.mix(hsla_green, percent(100)), hsla_red);
734 assert_approximately_eq!(hsla_red.mix(hsla_green, percent(0)), hsla_green);
735 assert_approximately_eq!(hsla_green.mix(hsla_red, percent(100)), hsla_green);
736 assert_approximately_eq!(hsla_green.mix(hsla_red, percent(0)), hsla_red);
737 assert_approximately_eq!(hsla_red.mix(hsla_green, percent(0)), hsla_green);
738 }
739
740 #[test]
741 fn can_mix_with_alpha() {
742 let red_rgba = rgba(100, 0, 0, 1.0);
743 let green_rgba = rgba(0, 100, 0, 0.5);
744 let brown_rgba = rgba(75, 25, 0, 0.75);
745 let green_hsla = hsla(120, 100, 20, 1.0);
746 let red_hsla = hsla(0, 100, 20, 1.0);
747 let brown_hsla = hsla(60, 100, 10, 1.0);
748
749 assert_approximately_eq!(red_rgba.mix(green_rgba, percent(50)), brown_rgba);
750 assert_approximately_eq!(green_rgba.mix(red_rgba, percent(50)), brown_rgba);
751 assert_approximately_eq!(red_hsla.mix(green_hsla, percent(50)), brown_hsla);
752 assert_approximately_eq!(green_hsla.mix(red_hsla, percent(50)), brown_hsla);
753 }
754
755 #[test]
756 fn can_tint() {
757 assert_approximately_eq!(
758 rgba(0, 0, 255, 0.5).tint(percent(50)),
759 rgba(191, 191, 255, 0.75)
760 );
761 assert_approximately_eq!(rgb(0, 0, 255).tint(percent(50)), rgb(128, 128, 255));
762 assert_approximately_eq!(hsl(6, 93, 71).tint(percent(50)), hsl(6, 92, 85));
763 assert_approximately_eq!(
764 hsla(6, 93, 71, 0.5).tint(percent(50)),
765 hsla(6, 95, 93, 0.75)
766 );
767 }
768
769 #[test]
770 fn can_shade() {
771 assert_approximately_eq!(
772 rgba(0, 0, 255, 0.5).shade(percent(50)),
773 rgba(0, 0, 64, 0.75)
774 );
775 assert_approximately_eq!(rgb(0, 0, 255).shade(percent(50)), rgb(0, 0, 128));
776 assert_approximately_eq!(hsl(6, 93, 71).shade(percent(50)), hsl(6, 38, 36));
777 assert_approximately_eq!(
778 hsla(6, 93, 71, 0.5).shade(percent(50)),
779 hsla(7, 38, 18, 0.75)
780 );
781 }
782
783 #[test]
784 fn can_greyscale() {
785 assert_approximately_eq!(rgb(128, 242, 13).greyscale(), rgb(128, 128, 128));
786 assert_approximately_eq!(
787 rgba(128, 242, 13, 1.0).greyscale(),
788 rgba(128, 128, 128, 1.0)
789 );
790 assert_approximately_eq!(hsl(90, 90, 50).greyscale(), hsl(90, 0, 50));
791 assert_approximately_eq!(hsla(90, 90, 50, 1.0).greyscale(), hsla(90, 0, 50, 1.0));
792 }
793
794 #[test]
795 fn can_clone() {
796 let rgb_color = rgb(5, 10, 15);
797 let rgba_color = rgba(5, 10, 15, 1.0);
798 let hsl_color = hsl(6, 93, 71);
799 let hsla_color = hsla(6, 93, 71, 1.0);
800
801 assert_eq!(rgb_color, rgb_color.clone());
802 assert_eq!(rgba_color, rgba_color.clone());
803 assert_eq!(hsl_color, hsl_color.clone());
804 assert_eq!(hsla_color, hsla_color.clone());
805 }
806
807 #[test]
808 fn can_copy() {
809 let rgb_color = rgb(172, 95, 82);
810 let rgba_color = rgba(172, 95, 82, 1.0);
811 let hsl_color = hsl(9, 35, 50);
812 let hsla_color = hsla(9, 35, 50, 1.0);
813
814 let copied_rgb_color = rgb_color;
815 let copied_rgba_color = rgba_color;
816 let copied_hsl_color = hsl_color;
817 let copied_hsla_color = hsla_color;
818
819 assert_eq!(rgb_color, copied_rgb_color);
820 assert_eq!(rgba_color, copied_rgba_color);
821 assert_eq!(hsl_color, copied_hsl_color);
822 assert_eq!(hsla_color, copied_hsla_color);
823 }
824
825 #[test]
826 fn can_debug() {
827 let rgb_value = format!("{:?}", rgb(5, 10, 15));
828 let rgba_value = format!("{:?}", rgba(5, 10, 15, 1.0));
829 let hsl_value = format!("{:?}", hsl(6, 93, 71));
830 let hsla_value = format!("{:?}", hsla(6, 93, 71, 1.0));
831
832 assert_eq!(rgb_value, "RGB { r: Ratio(5), g: Ratio(10), b: Ratio(15) }");
833 assert_eq!(
834 rgba_value,
835 "RGBA { r: Ratio(5), g: Ratio(10), b: Ratio(15), a: Ratio(255) }"
836 );
837 assert_eq!(
838 hsl_value,
839 "HSL { h: Angle { degrees: 6 }, s: Ratio(237), l: Ratio(181) }"
840 );
841 assert_eq!(
842 hsla_value,
843 "HSLA { h: Angle { degrees: 6 }, s: Ratio(237), l: Ratio(181), a: Ratio(255) }"
844 );
845 }
846
847 #[test]
848 fn can_convert_to_css() {
849 let rgb = rgb(5, 10, 255);
850 let rgba = rgba(5, 10, 255, 1.0);
851 let hsl = hsl(6, 93, 71);
852 let hsla = hsla(6, 93, 71, 1.0);
853
854 assert_eq!(rgb.to_css(), "rgb(5, 10, 255)");
855 assert_eq!(rgba.to_css(), "rgba(5, 10, 255, 1.00)");
856 assert_eq!(hsl.to_css(), "hsl(6, 93%, 71%)");
857 assert_eq!(hsla.to_css(), "hsla(6, 93%, 71%, 1.00)");
858 }
859
860 #[test]
861 fn can_print_in_css() {
862 let printed_rgb = format!("{}", rgb(5, 10, 255));
863 let printed_rgba = format!("{}", rgba(5, 10, 255, 1.0));
864 let printed_hsl = format!("{}", hsl(6, 93, 71));
865 let printed_hsla = format!("{}", hsla(6, 93, 71, 1.0));
866
867 assert_eq!(printed_rgb, "rgb(5, 10, 255)");
868 assert_eq!(printed_rgba, "rgba(5, 10, 255, 1.00)");
869 assert_eq!(printed_hsl, "hsl(6, 93%, 71%)");
870 assert_eq!(printed_hsla, "hsla(6, 93%, 71%, 1.00)");
871 }
872
873 #[test]
874 fn can_be_displayed() {
875 let rgb = rgb(5, 10, 255);
876 let rgba = rgba(5, 10, 255, 0.75);
877 let hsl = hsl(6, 93, 71);
878 let hsla = hsla(6, 93, 71, 1.0);
879
880 assert_eq!("rgb(5, 10, 255)".to_owned(), format!("{}", rgb));
881 assert_eq!("rgba(5, 10, 255, 0.75)".to_owned(), format!("{}", rgba));
882 assert_eq!("hsl(6, 93%, 71%)".to_owned(), format!("{}", hsl));
883 assert_eq!("hsla(6, 93%, 71%, 1.00)".to_owned(), format!("{}", hsla));
884 }
885
886 #[test]
887 fn can_be_stringified() {
888 let rgb = rgb(5, 10, 255);
889 let rgba = rgba(5, 10, 255, 0.5);
890 let hsl = hsl(6, 93, 71);
891 let hsla = hsla(6, 93, 71, 0.5);
892
893 assert_eq!(String::from("rgb(5, 10, 255)"), rgb.to_string());
894 assert_eq!(String::from("rgba(5, 10, 255, 0.50)"), rgba.to_string());
895 assert_eq!(String::from("hsl(6, 93%, 71%)"), hsl.to_string());
896 assert_eq!(String::from("hsla(6, 93%, 71%, 0.50)"), hsla.to_string());
897 }
898}