use crate::ppm::PNM;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct Color {
pub r: u8,
pub g: u8,
pub b: u8,
}
impl Color {
pub fn new(r: u8, g: u8, b: u8) -> Self {
Self { r, g, b }
}
pub fn splat(val: u8) -> Self {
Self {
r: val,
g: val,
b: val,
}
}
pub fn from_u8_array(vals: &[u8]) -> Self {
assert_eq!(vals.len(), 3);
Self::new(vals[0], vals[1], vals[2])
}
}
impl ToString for Color {
fn to_string(&self) -> String {
format!("({},{},{})", self.r, self.g, self.b)
}
}
impl PNM for Color {
fn to_pnm_p3(&self) -> String {
format!("{} {} {}", self.r, self.g, self.b)
}
fn to_pnm_p6(&self) -> Vec<u8> {
vec![self.r, self.g, self.b]
}
}
#[macro_export]
macro_rules! rgb {
() => {
$crate::color::Color::default()
};
($val:expr) => {
$crate::color::Color::splat($val)
};
($r:expr, $g:expr, $b:expr) => {
$crate::color::Color::new($r, $g, $b)
};
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_color_new() {
assert_eq!(
Color::new(10, 42, 128),
Color {
r: 10,
g: 42,
b: 128
}
);
}
#[test]
fn test_color_default() {
assert_eq!(Color::default(), Color { r: 0, g: 0, b: 0 });
}
#[test]
fn test_color_splat() {
assert_eq!(
Color::splat(17),
Color {
r: 17,
g: 17,
b: 17
}
);
assert_eq!(
Color::splat(42),
Color {
r: 42,
g: 42,
b: 42
}
);
}
#[test]
fn test_color_from_u8_array() {
assert_eq!(
Color::from_u8_array(&[13, 42, 9]),
Color { r: 13, g: 42, b: 9 }
);
}
#[test]
fn test_macro_empty() {
assert_eq!(rgb!(), Color { r: 0, g: 0, b: 0 });
}
#[test]
fn test_macro_splat() {
assert_eq!(
rgb!(42),
Color {
r: 42,
g: 42,
b: 42
}
);
}
#[test]
fn test_macro_three_values() {
assert_eq!(
rgb!(17, 42, 128),
Color {
r: 17,
g: 42,
b: 128
}
);
}
}