use crate::pixelcolor::PixelColor;
use core::convert::TryFrom;
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
#[non_exhaustive]
pub struct PrimitiveStyle<C>
where
C: PixelColor,
{
pub fill_color: Option<C>,
pub stroke_color: Option<C>,
pub stroke_width: u32,
}
impl<C> PrimitiveStyle<C>
where
C: PixelColor,
{
pub fn new() -> Self {
Self::default()
}
pub fn with_stroke(stroke_color: C, stroke_width: u32) -> Self {
Self {
stroke_color: Some(stroke_color),
stroke_width,
..PrimitiveStyle::default()
}
}
pub fn with_fill(fill_color: C) -> Self {
Self {
fill_color: Some(fill_color),
..PrimitiveStyle::default()
}
}
pub(crate) fn stroke_width_i32(&self) -> i32 {
i32::try_from(self.stroke_width).unwrap_or(i32::max_value())
}
}
impl<C> Default for PrimitiveStyle<C>
where
C: PixelColor,
{
fn default() -> Self {
Self {
fill_color: None,
stroke_color: None,
stroke_width: 0,
}
}
}
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default)]
pub struct PrimitiveStyleBuilder<C>
where
C: PixelColor,
{
style: PrimitiveStyle<C>,
}
impl<C> PrimitiveStyleBuilder<C>
where
C: PixelColor,
{
pub fn new() -> Self {
Self {
style: PrimitiveStyle::default(),
}
}
pub fn fill_color(mut self, fill_color: C) -> Self {
self.style.fill_color = Some(fill_color);
self
}
pub fn stroke_color(mut self, stroke_color: C) -> Self {
self.style.stroke_color = Some(stroke_color);
self
}
pub fn stroke_width(mut self, stroke_width: u32) -> Self {
self.style.stroke_width = stroke_width;
self
}
pub fn build(self) -> PrimitiveStyle<C> {
self.style
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::pixelcolor::{BinaryColor, Rgb888, RgbColor};
#[test]
fn default_style() {
assert_eq!(
PrimitiveStyle::<BinaryColor>::default(),
PrimitiveStyle {
fill_color: None,
stroke_color: None,
stroke_width: 0,
}
);
assert_eq!(
PrimitiveStyle::<BinaryColor>::default(),
PrimitiveStyle::new()
);
}
#[test]
fn constructors() {
let style = PrimitiveStyle::with_fill(Rgb888::RED);
assert_eq!(style.fill_color, Some(Rgb888::RED));
assert_eq!(style.stroke_color, None);
let style = PrimitiveStyle::with_stroke(Rgb888::GREEN, 123);
assert_eq!(style.fill_color, None);
assert_eq!(style.stroke_color, Some(Rgb888::GREEN));
assert_eq!(style.stroke_width, 123);
}
#[test]
fn stroke_width_i32() {
let mut style: PrimitiveStyle<BinaryColor> = PrimitiveStyle::default();
style.stroke_width = 1;
assert_eq!(style.stroke_width_i32(), 1);
style.stroke_width = 0x7FFFFFFF;
assert_eq!(style.stroke_width_i32(), 0x7FFFFFFF);
style.stroke_width = 0x80000000;
assert_eq!(style.stroke_width_i32(), 0x7FFFFFFF);
style.stroke_width = 0xFFFFFFFF;
assert_eq!(style.stroke_width_i32(), 0x7FFFFFFF);
}
#[test]
fn builder_default() {
assert_eq!(
PrimitiveStyleBuilder::<BinaryColor>::new().build(),
PrimitiveStyle::<BinaryColor>::default()
);
}
#[test]
fn builder_stroke() {
assert_eq!(
PrimitiveStyleBuilder::new()
.stroke_color(BinaryColor::On)
.stroke_width(10)
.build(),
PrimitiveStyle::with_stroke(BinaryColor::On, 10)
);
}
#[test]
fn builder_fill() {
assert_eq!(
PrimitiveStyleBuilder::new()
.fill_color(BinaryColor::On)
.build(),
PrimitiveStyle::with_fill(BinaryColor::On)
);
}
}