1use std::ops::{Add, AddAssign, Mul, Sub, SubAssign};
3
4use winit::dpi::Size;
5
6#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
8pub struct Vec2<T> {
9 pub x: T,
10 pub y: T,
11}
12
13impl<T> Vec2<T> {
14 pub fn new(x: T, y: T) -> Self {
15 Self { x, y }
16 }
17
18 pub fn to_raw(self) -> [T; 2] {
19 [self.x, self.y]
20 }
21}
22
23#[macro_export]
24macro_rules! vec2 {
25 ($x:expr, $y:expr) => {
26 Vec2 { x: $x, y: $y }
27 };
28
29 ($x:expr) => {
30 Vec2 { x: $x, y: $x }
31 };
32}
33
34macro_rules! from_vec2_impl {
35 ($type_one:ident, $type_two:ident) => {
36 impl From<Vec2<$type_two>> for Vec2<$type_one> {
37 fn from(value: Vec2<$type_two>) -> Self {
38 Vec2 {
39 x: $type_one::from(value.x),
40 y: $type_one::from(value.y),
41 }
42 }
43 }
44 };
45}
46
47from_vec2_impl!(i128, i8);
48from_vec2_impl!(i128, i16);
49from_vec2_impl!(i128, i32);
50from_vec2_impl!(i128, i64);
51from_vec2_impl!(i128, u8);
52from_vec2_impl!(i128, u16);
53from_vec2_impl!(i128, u32);
54from_vec2_impl!(i128, u64);
55from_vec2_impl!(i64, i8);
56from_vec2_impl!(i64, i16);
57from_vec2_impl!(i64, i32);
58from_vec2_impl!(i64, u8);
59from_vec2_impl!(i64, u16);
60from_vec2_impl!(i64, u32);
61from_vec2_impl!(i32, i8);
62from_vec2_impl!(i32, i16);
63from_vec2_impl!(i32, u8);
64from_vec2_impl!(i32, u16);
65from_vec2_impl!(i16, i8);
66from_vec2_impl!(i16, u8);
67from_vec2_impl!(u128, u8);
68from_vec2_impl!(u128, u16);
69from_vec2_impl!(u128, u32);
70from_vec2_impl!(u128, u64);
71from_vec2_impl!(u64, u8);
72from_vec2_impl!(u64, u16);
73from_vec2_impl!(u64, u32);
74from_vec2_impl!(u32, u8);
75from_vec2_impl!(u32, u16);
76from_vec2_impl!(u16, u8);
77from_vec2_impl!(f64, f32);
78from_vec2_impl!(f64, i32);
79from_vec2_impl!(f64, i16);
80from_vec2_impl!(f64, i8);
81from_vec2_impl!(f64, u32);
82from_vec2_impl!(f64, u16);
83from_vec2_impl!(f64, u8);
84from_vec2_impl!(f32, i16);
85from_vec2_impl!(f32, i8);
86from_vec2_impl!(f32, u16);
87from_vec2_impl!(f32, u8);
88
89impl<T: Mul<Output = T> + Copy> Vec2<T> {
90 pub fn scale(self, number: T) -> Vec2<T> {
91 Vec2 {
92 x: self.x * number,
93 y: self.y * number,
94 }
95 }
96}
97
98impl<T> From<Vec2<T>> for (T, T) {
99 fn from(value: Vec2<T>) -> Self {
100 (value.x, value.y)
101 }
102}
103
104impl From<Vec2<u32>> for glyphon::Resolution {
105 fn from(value: Vec2<u32>) -> Self {
106 Self {
107 width: value.x,
108 height: value.y,
109 }
110 }
111}
112
113impl From<Size> for Vec2<u32> {
114 fn from(value: Size) -> Self {
115 match value {
116 Size::Physical(s) => vec2!(s.width, s.height),
117 Size::Logical(s) => vec2!(s.width as u32, s.height as u32),
118 }
119 }
120}
121
122impl<T> From<(T, T)> for Vec2<T> {
123 fn from(value: (T, T)) -> Self {
124 Vec2 {
125 x: value.0,
126 y: value.1,
127 }
128 }
129}
130
131impl<T> From<winit::dpi::PhysicalSize<T>> for Vec2<T> {
132 fn from(value: winit::dpi::PhysicalSize<T>) -> Self {
133 Vec2 {
134 x: value.width,
135 y: value.height,
136 }
137 }
138}
139
140impl From<glam::Vec2> for Vec2<f32> {
141 fn from(value: glam::Vec2) -> Self {
142 Self {
143 x: value.x,
144 y: value.y,
145 }
146 }
147}
148
149impl From<Vec2<f32>> for glam::Vec2 {
150 fn from(val: Vec2<f32>) -> Self {
151 Self { x: val.x, y: val.y }
152 }
153}
154
155impl<T: Add<Output = T>> Add for Vec2<T> {
156 type Output = Vec2<T>;
157 fn add(self, rhs: Self) -> Self::Output {
158 Self {
159 x: self.x + rhs.x,
160 y: self.y + rhs.y,
161 }
162 }
163}
164
165impl<T: Sub<Output = T>> Sub for Vec2<T> {
166 type Output = Vec2<T>;
167 fn sub(self, rhs: Self) -> Self::Output {
168 Self {
169 x: self.x - rhs.x,
170 y: self.y - rhs.y,
171 }
172 }
173}
174
175impl<T: AddAssign> AddAssign for Vec2<T> {
176 fn add_assign(&mut self, rhs: Self) {
177 self.x += rhs.x;
178 self.y += rhs.y;
179 }
180}
181
182impl<T: SubAssign> SubAssign for Vec2<T> {
183 fn sub_assign(&mut self, rhs: Self) {
184 self.x -= rhs.x;
185 self.y -= rhs.y;
186 }
187}