1use crate::Direction;
2use serde::{Deserialize, Serialize};
3use std::fmt::{Debug, Display, Formatter};
4
5#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Serialize, Deserialize)]
6pub struct Joint {
7 pub x: isize,
8 pub y: isize,
9 pub direction: Direction,
10}
11
12impl Debug for Joint {
13 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
14 f.debug_struct("Joint").field("x", &self.x).field("y", &self.y).field("direction", &self.direction.to_string()).finish()
15 }
16}
17
18impl Display for Joint {
19 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
20 f.debug_tuple("Joint").field(&self.x).field(&self.y).field(&self.direction.to_string()).finish()
21 }
22}
23
24impl Joint {
25 pub fn new(x: isize, y: isize, direction: Direction) -> Self {
26 Self { x, y, direction }
27 }
28 pub fn from_point((x1, y1): (isize, isize), (x2, y2): (isize, isize)) -> Option<Self> {
29 if x1 == x2 {
30 if y1 == y2 + 1 {
31 return Some(Self::new(x1, y1, Direction::Y(false)));
32 }
33 else if y1 == y2 - 1 {
34 return Some(Self::new(x1, y1, Direction::Y(true)));
35 }
36 }
37 else if y1 == y2 {
38 if x1 == x2 + 1 {
39 return Some(Self::new(x1, y1, Direction::X(false)));
40 }
41 else if x1 == x2 - 1 {
42 return Some(Self::new(x1, y1, Direction::X(true)));
43 }
44 }
45 None
46 }
47
48 pub fn source(&self) -> (isize, isize) {
49 (self.x, self.y)
50 }
51 pub fn target(&self) -> (isize, isize) {
52 match self.direction {
53 Direction::X(true) => (self.x + 1, self.y),
54 Direction::X(false) => (self.x - 1, self.y),
55 Direction::Y(true) => (self.x, self.y + 1),
56 Direction::Y(false) => (self.x, self.y - 1),
57 }
58 }
59}