use std::fmt::Display;
use std::ops::{Add, AddAssign, Index, IndexMut, Mul, MulAssign, Sub, SubAssign};
#[derive(Debug, PartialEq, Clone, Copy, Default)]
pub struct Color {
r: f64,
g: f64,
b: f64,
}
impl Color {
pub fn new(r: f64, g: f64, b: f64) -> Self {
Self { r, g, b }
}
pub fn r(&self) -> f64 {
self.r
}
pub fn g(&self) -> f64 {
self.g
}
pub fn b(&self) -> f64 {
self.b
}
}
impl Display for Color {
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
let r = ((self.r * 256.0) as i32).clamp(0, 255);
let g = ((self.g * 256.0) as i32).clamp(0, 255);
let b = ((self.b * 256.0) as i32).clamp(0, 255);
write!(f, "{} {} {}", r, g, b)
}
}
impl Add for Color {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Self::Output::new(self.r + rhs.r, self.g + rhs.g, self.b + rhs.b)
}
}
impl AddAssign for Color {
fn add_assign(&mut self, rhs: Self) {
self.r += rhs.r;
self.g += rhs.g;
self.b += rhs.b;
}
}
impl Sub for Color {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
Self::Output::new(self.r - rhs.r, self.g - rhs.g, self.b - rhs.b)
}
}
impl SubAssign for Color {
fn sub_assign(&mut self, rhs: Self) {
self.r -= rhs.r;
self.g -= rhs.g;
self.b -= rhs.b;
}
}
impl Mul for Color {
type Output = Self;
fn mul(self, rhs: Self) -> Self::Output {
Self::Output::new(self.r * rhs.r, self.g * rhs.g, self.b * rhs.b)
}
}
impl MulAssign for Color {
fn mul_assign(&mut self, rhs: Self) {
self.r *= rhs.r;
self.g *= rhs.g;
self.b *= rhs.b;
}
}
impl Mul<f64> for Color {
type Output = Self;
fn mul(self, rhs: f64) -> Self::Output {
Self::Output::new(self.r * rhs, self.g * rhs, self.b * rhs)
}
}
impl MulAssign<f64> for Color {
fn mul_assign(&mut self, rhs: f64) {
self.r *= rhs;
self.g *= rhs;
self.b *= rhs;
}
}
impl Index<usize> for Color {
type Output = f64;
fn index(&self, index: usize) -> &Self::Output {
match index {
0 => &self.r,
1 => &self.g,
2 => &self.b,
_ => panic!("Index out of bounds for color, got {}", index),
}
}
}
impl IndexMut<usize> for Color {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
match index {
0 => &mut self.r,
1 => &mut self.g,
2 => &mut self.b,
_ => panic!("Index out of bounds for color, got {}", index),
}
}
}