common/rust: add Line type
This commit is contained in:
parent
26700274c3
commit
7db15c9cf7
1 changed files with 56 additions and 2 deletions
|
@ -6,8 +6,8 @@ use std::{
|
|||
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct Vec2 {
|
||||
x: i32, // increases toward right
|
||||
y: i32, // increases toward top
|
||||
pub x: i32, // increases toward right
|
||||
pub y: i32, // increases toward top
|
||||
}
|
||||
|
||||
impl Vec2 {
|
||||
|
@ -140,3 +140,57 @@ impl FromStr for Direction {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A line from one point to another.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct Line {
|
||||
pub start: Vec2,
|
||||
pub end: Vec2,
|
||||
}
|
||||
|
||||
impl Line {
|
||||
/// Returns an iterator over the line's points represented as [`Vec2`], including the start and
|
||||
/// end points.
|
||||
///
|
||||
/// Only works for orthogonal lines.
|
||||
#[must_use]
|
||||
pub fn points(self) -> Option<LinePoints> {
|
||||
LinePoints::try_from(self).ok()
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator over a line's points. See [`Line::points()`] for details.
|
||||
pub struct LinePoints {
|
||||
line: Option<Line>,
|
||||
}
|
||||
|
||||
impl TryFrom<Line> for LinePoints {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(line: Line) -> Result<Self, Self::Error> {
|
||||
if line.start.x == line.end.x || line.start.y == line.end.y {
|
||||
Ok(Self { line: Some(line) })
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for LinePoints {
|
||||
type Item = Vec2;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let Some(line) = self.line.as_mut() else { return None };
|
||||
|
||||
let delta = (line.end - line.start).map(i32::signum);
|
||||
|
||||
let p = line.start;
|
||||
line.start += delta;
|
||||
|
||||
if delta == Vec2::new(0, 0) {
|
||||
self.line = None;
|
||||
}
|
||||
|
||||
Some(p)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue