1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
use direction::Orientation;
use std::iter;
#[derive(Debug,Clone,Copy,PartialEq)]
pub struct XY<T> {
pub x: T,
pub y: T,
}
impl<T> XY<T> {
pub fn new(x: T, y: T) -> Self {
XY { x: x, y: y }
}
pub fn map<U, F: Fn(T) -> U>(self, f: F) -> XY<U> {
XY::new(f(self.x), f(self.y))
}
pub fn pair(self) -> (T, T) {
(self.x, self.y)
}
pub fn as_ref(&self) -> XY<&T> {
XY::new(&self.x, &self.y)
}
pub fn iter(&self) -> iter::Chain<iter::Once<&T>, iter::Once<&T>> {
iter::once(&self.x).chain(iter::once(&self.y))
}
pub fn get(&self, o: Orientation) -> &T {
match o {
Orientation::Horizontal => &self.x,
Orientation::Vertical => &self.y,
}
}
pub fn zip<U>(self, other: XY<U>) -> XY<(T, U)> {
XY::new((self.x, other.x), (self.y, other.y))
}
pub fn zip_map<U, V, F: Fn(T, U) -> V>(self, other: XY<U>, f: F) -> XY<V> {
XY::new(f(self.x, other.x), f(self.y, other.y))
}
}
impl<T> XY<Option<T>> {
pub fn unwrap_or(self, other: XY<T>) -> XY<T> {
self.zip_map(other, |s, o| s.unwrap_or(o))
}
}
impl XY<bool> {
pub fn any(&self) -> bool {
self.x || self.y
}
pub fn both(&self) -> bool {
self.x && self.y
}
}
impl<T: Copy> XY<T> {
pub fn both_from(value: T) -> Self {
XY::new(value, value)
}
}
impl<T> From<(T, T)> for XY<T> {
fn from((x, y): (T, T)) -> Self {
XY::new(x, y)
}
}