diff --git a/color/Cargo.lock b/color/Cargo.lock new file mode 100644 index 0000000..584386e --- /dev/null +++ b/color/Cargo.lock @@ -0,0 +1,32 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "approx" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f2a05fd1bd10b2527e20a2cd32d8873d115b8b39fe219ee25f42a8aca6ba278" +dependencies = [ + "num-traits", +] + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "color" +version = "0.1.0" +dependencies = [ + "approx", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] diff --git a/color/Cargo.toml b/color/Cargo.toml new file mode 100644 index 0000000..c8300ab --- /dev/null +++ b/color/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "color" +version = "0.1.0" +authors = ["Jon Janzen "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +approx = "0.4" diff --git a/color/src/lib.rs b/color/src/lib.rs new file mode 100644 index 0000000..6d178aa --- /dev/null +++ b/color/src/lib.rs @@ -0,0 +1,127 @@ +#[macro_use] +extern crate approx; + +use std::ops; + +#[derive(Debug)] +struct Color { + red: f32, + green: f32, + blue: f32, +} + +impl Color { + pub fn new(red: f32, green: f32, blue: f32) -> Color { + Color { + red, + green, + blue, + } + } +} + +impl PartialEq for Color { + fn eq(&self, _rhs: &Self) -> bool { + relative_eq!(self.red, _rhs.red) + && relative_eq!(self.green, _rhs.green) + && relative_eq!(self.blue, _rhs.blue) + } +} + +impl ops::Add for Color { + type Output = Color; + + fn add(self, _rhs: Color) -> Color { + Color::new( + self.red + _rhs.red, + self.green + _rhs.green, + self.blue + _rhs.blue, + ) + } + +} + +impl ops::Mul for Color { + type Output = Color; + + fn mul(self, _rhs: Color) -> Color { + Color::new( + self.red * _rhs.red, + self.green * _rhs.green, + self.blue * _rhs.blue, + ) + } +} + +impl ops::Mul for Color { + type Output = Color; + + fn mul(self, _rhs: i32) -> Color { + let val = _rhs as f32; + Color::new( + self.red * val, + self.green * val, + self.blue * val, + ) + } +} + +impl ops::Sub for Color { + type Output = Color; + + fn sub(self, _rhs: Color) -> Color { + Color::new( + self.red - _rhs.red, + self.green - _rhs.green, + self.blue - _rhs.blue, + ) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn color() { + let c = Color::new(-0.5, 0.4, 1.7); + assert_eq!(-0.5, c.red); + assert_eq!(0.4, c.green); + assert_eq!(1.7, c.blue); + } + + #[test] + fn add() { + let c1 = Color::new(0.9, 0.6, 0.75); + let c2 = Color::new(0.7, 0.1, 0.25); + let res = Color::new(1.6, 0.7, 1.0); + + assert_eq!(res, c1 + c2); + } + + #[test] + fn sub() { + let c1 = Color::new(0.9, 0.6, 0.75); + let c2 = Color::new(0.7, 0.1, 0.25); + let res = Color::new(0.2, 0.5, 0.5); + + assert_eq!(res, c1 - c2); + } + + #[test] + fn mul_by_scalar() { + let c = Color::new(0.9, 0.6, 0.75); + let res = Color::new(1.8, 1.2, 1.5); + + assert_eq!(res, c * 2); + } + + #[test] + fn mul() { + let c1 = Color::new(1.0, 0.2, 0.4); + let c2 = Color::new(0.9, 1.0, 0.1); + let res = Color::new(0.9, 0.2, 0.04); + + assert_eq!(res, c1 * c2); + } +}