use super::run;
use crate::cell::Side;
use crate::{Arm, Cell, Orientation, Pos, Shape, Stroke, StrokeCell, Surface};
#[derive(Debug)]
pub(crate) struct Segment {
pub(crate) from: Pos,
pub(crate) len: u16,
pub(crate) orientation: Orientation,
pub(crate) stroke: Stroke,
}
impl Shape for Segment {
fn draw(&self, surface: &mut dyn Surface) {
let (a, b) = match self.orientation {
Orientation::Horizontal => (Side::Left, Side::Right),
Orientation::Vertical => (Side::Top, Side::Bottom),
};
let arm_toward = |side: Side| {
if side == a || side == b {
Arm::Set(self.stroke.clone())
} else {
Arm::Unset
}
};
let cell: Cell = StrokeCell {
base: self.stroke.clone(),
top: arm_toward(Side::Top),
right: arm_toward(Side::Right),
bottom: arm_toward(Side::Bottom),
left: arm_toward(Side::Left),
}
.into();
for at in run(self.from, self.len, self.orientation) {
surface.stamp(at, cell.clone());
}
}
}
#[cfg(test)]
mod tests {
use super::Segment;
use crate::{
Arm, Buffer, Cell, CellReader, FigureLayer, Orientation, Pos, Shape, Size, StampMode,
Stroke, StrokeCell, Window,
};
#[test]
fn a_horizontal_segment_sets_left_and_right() {
let mut buffer = Buffer::new(Window {
origin: Pos { x: 0, y: 0 },
size: Size {
width: 3,
height: 1,
},
});
let mut layer = FigureLayer::new(&mut buffer, StampMode::Above);
Segment {
from: Pos { x: 0, y: 0 },
len: 3,
orientation: Orientation::Horizontal,
stroke: Stroke::from("light"),
}
.draw(&mut layer);
for x in 0..3 {
assert_eq!(
buffer.cell(Pos { x, y: 0 }),
Some(&Cell::from(StrokeCell {
base: Stroke::from("light"),
top: Arm::Unset,
right: Arm::Set(Stroke::from("light")),
bottom: Arm::Unset,
left: Arm::Set(Stroke::from("light")),
})),
"position ({x}, 0)"
);
}
}
}