use std::fmt::Display;
use self::{color::PixelColor, position::PixelPosition};
pub mod canvas;
pub mod color;
pub mod maybe;
pub mod position;
pub trait PixelInitializer: PixelInterface {
fn new(color: impl Into<Self::ColorType>, position: impl Into<PixelPosition>) -> Self;
}
pub trait PixelInterface {
type ColorType;
fn has_color(&self) -> bool;
fn color(&self) -> &Self::ColorType;
fn position(&self) -> &PixelPosition;
}
pub trait PixelMutInterface: PixelInterface {
fn update_color(&mut self, color: impl Into<Self::ColorType>) -> Self::ColorType;
}
pub(crate) trait PixelMutPosition {
fn update_position(&mut self, pos: PixelPosition);
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Pixel {
pub color: PixelColor,
position: PixelPosition,
}
impl PixelMutPosition for Pixel {
fn update_position(&mut self, pos: PixelPosition) {
self.position = pos;
}
}
impl Display for Pixel {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "pixel({}, {})", self.color, self.position)
}
}
impl PixelInterface for Pixel {
type ColorType = PixelColor;
fn color(&self) -> &PixelColor {
&self.color
}
fn position(&self) -> &PixelPosition {
&self.position
}
fn has_color(&self) -> bool {
true
}
}
impl PixelMutInterface for Pixel {
fn update_color(&mut self, color: impl Into<Self::ColorType>) -> Self::ColorType {
std::mem::replace(&mut self.color, color.into()).into()
}
}
impl PixelInterface for &Pixel {
type ColorType = PixelColor;
fn color(&self) -> &PixelColor {
&self.color
}
fn position(&self) -> &PixelPosition {
&self.position
}
fn has_color(&self) -> bool {
true
}
}
impl PixelInterface for &mut Pixel {
type ColorType = PixelColor;
fn color(&self) -> &PixelColor {
&self.color
}
fn position(&self) -> &PixelPosition {
&self.position
}
fn has_color(&self) -> bool {
true
}
}
impl PixelMutInterface for &mut Pixel {
fn update_color(&mut self, color: impl Into<Self::ColorType>) -> Self::ColorType {
std::mem::replace(&mut self.color, color.into()).into()
}
}
impl PixelInitializer for Pixel {
fn new(color: impl Into<PixelColor>, position: impl Into<PixelPosition>) -> Self {
Self {
color: color.into(),
position: position.into(),
}
}
}
pub trait IntoPixel {
fn into_pixel(self) -> Pixel;
}
impl<T> IntoPixel for T
where
T: Into<Pixel>,
{
fn into_pixel(self) -> Pixel {
self.into()
}
}
pub trait PixelIterExt<Item: PixelInterface>: Iterator<Item = Item> {
fn filter_color(
self,
color: impl Into<<Self::Item as PixelInterface>::ColorType>,
) -> impl Iterator<Item = Item>
where
Self: Sized,
<Item as PixelInterface>::ColorType: PartialEq,
{
let color: <Self::Item as PixelInterface>::ColorType = color.into();
self.filter(move |pixel| pixel.color() == &color)
}
fn filter_position<P>(self, mut predicate: P) -> impl Iterator<Item = Item>
where
Self: Sized,
P: FnMut(&PixelPosition) -> bool,
{
self.filter(move |pixel| predicate(pixel.position()))
}
}
impl<'p, T> PixelIterExt<Pixel> for T where T: Iterator<Item = Pixel> {}
impl<'p, T> PixelIterExt<&'p Pixel> for T where T: Iterator<Item = &'p Pixel> {}
impl<'p, T> PixelIterExt<&'p mut Pixel> for T where T: Iterator<Item = &'p mut Pixel> {}
pub trait PixelIterMutExt<'p, Item: PixelMutInterface>: Iterator<Item = Item> {
fn update_colors(self, color: impl Into<<Self::Item as PixelInterface>::ColorType>)
where
Self: Sized,
<Self::Item as PixelInterface>::ColorType: Clone,
{
let color = color.into();
self.for_each(move |mut pixel| {
pixel.update_color(color.clone());
})
}
}
impl<'p, T> PixelIterMutExt<'p, &'p mut Pixel> for T where T: Iterator<Item = &'p mut Pixel> {}