ceratophrys 0.0.3

Library to draw pixel art as code
Documentation
use crate::{Color, Image, Pixel, Position, Size};

#[derive(Debug, Clone, Copy)]
pub struct Rectangle {
    pub color: Color,
    pub position: Position,
    pub size: Size,
    pub fill: bool,
}

impl Rectangle {
    pub const fn new() -> Self {
        Self {
            color: Color::BLACK,
            position: Position::ORIGIN,
            size: Size::EMPTY,
            fill: false,
        }
    }

    pub const fn color(self, color: Color) -> Self {
        Self { color, ..self }
    }

    pub const fn position(self, position: Position) -> Self {
        Self { position, ..self }
    }

    pub const fn size(self, size: Size) -> Self {
        Self { size, ..self }
    }

    pub const fn fill(self) -> Self {
        Self { fill: true, ..self }
    }

    pub fn to_image(self) -> Image {
        self.into_iter().collect()
    }
}

impl Default for Rectangle {
    fn default() -> Self {
        Self::new()
    }
}

impl IntoIterator for Rectangle {
    type Item = Pixel;
    type IntoIter = Box<dyn Iterator<Item = Pixel>>;

    fn into_iter(self) -> Self::IntoIter {
        if self.fill || self.size.is_empty() {
            return Box::new(
                self.size
                    .positions()
                    .map(move |p| Pixel::new(self.position + p, self.color)),
            );
        }

        let pixel = Pixel::new(self.position, self.color);
        let mut pixels = Vec::new();
        for x in 0..self.size.width {
            pixels.push(pixel.map_position(|p| p.move_x_unsigned(x)));
            pixels.push(pixel.map_position(|p| p.move_xy_unsigned(x, self.size.height - 1)));
        }
        for y in 0..self.size.height {
            pixels.push(pixel.map_position(|p| p.move_y_unsigned(y)));
            pixels.push(pixel.map_position(|p| p.move_xy_unsigned(self.size.width - 1, y)));
        }
        pixels.sort();
        pixels.dedup();
        Box::new(pixels.into_iter())
    }
}