1#[macro_export]
17macro_rules! define_index {
18 ($name:ident, $inner:ty, $doc:expr) => {
19 #[doc = $doc]
20 #[repr(transparent)]
21 #[derive(
22 Debug,
23 Clone,
24 Copy,
25 PartialEq,
26 Eq,
27 Hash,
28 PartialOrd,
29 Ord,
30 serde::Serialize,
31 serde::Deserialize,
32 )]
33 pub struct $name($inner);
34
35 impl $name {
36 pub const fn from(var: $inner) -> Self {
38 Self(var)
39 }
40
41 pub const fn get(&self) -> $inner {
43 self.0
44 }
45 }
46
47 impl std::ops::Deref for $name {
48 type Target = $inner;
49
50 fn deref(&self) -> &Self::Target {
51 &self.0
52 }
53 }
54
55 impl From<$inner> for $name {
56 fn from(value: $inner) -> Self {
57 $name(value)
58 }
59 }
60
61 impl From<$name> for $inner {
62 fn from(value: $name) -> Self {
63 value.0
64 }
65 }
66
67 impl std::fmt::Display for $name {
68 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
69 write!(f, "{}", self.0)
70 }
71 }
72 };
73}
74
75#[macro_export]
90macro_rules! define_nonzero_count {
91 ($name:ident, $base:ty, $doc:expr) => {
92 #[doc = $doc]
93 #[derive(
94 Debug,
95 Clone,
96 Copy,
97 PartialEq,
98 Eq,
99 Hash,
100 PartialOrd,
101 Ord,
102 serde::Serialize,
103 serde::Deserialize,
104 )]
105 pub struct $name {
106 value: $base,
107 }
108
109 impl $name {
110 pub fn new(value: $base) -> Result<Self, FeagiDataError> {
112 if value == 0 {
113 return Err(FeagiDataError::BadParameters(
114 "Count cannot be zero!".into(),
115 ));
116 }
117 Ok($name { value })
118 }
119 }
120 impl TryFrom<$base> for $name {
121 type Error = FeagiDataError;
122 fn try_from(value: $base) -> Result<Self, FeagiDataError> {
123 $name::new({ value })
124 }
125 }
126
127 impl From<$name> for $base {
128 fn from(value: $name) -> $base {
129 value.value
130 }
131 }
132
133 impl std::ops::Deref for $name {
134 type Target = $base;
135 fn deref(&self) -> &Self::Target {
136 &self.value
137 }
138 }
139
140 impl std::fmt::Display for $name {
141 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
142 self.value.fmt(f)
143 }
144 }
145 };
146}
147
148#[macro_export]
166macro_rules! define_xy_coordinates {
167 ($name:ident, $var_type:ty, $friendly_name:expr, $doc_string:expr) => {
168 #[doc = $doc_string]
169 #[derive(Clone, Debug, PartialEq, Eq, Hash, Copy, serde::Serialize, serde::Deserialize)]
170 pub struct $name {
171 pub x: $var_type,
172 pub y: $var_type,
173 }
174
175 impl $name {
176 pub fn new(x: $var_type, y: $var_type) -> Self {
177 Self { x, y }
178 }
179 }
180
181 impl From<$name> for ($var_type, $var_type) {
182 fn from(value: $name) -> Self {
183 (value.x, value.y)
184 }
185 }
186
187 impl From<($var_type, $var_type)> for $name {
188 fn from(value: ($var_type, $var_type)) -> Self {
189 $name::new(value.0, value.1)
190 }
191 }
192
193 impl std::fmt::Display for $name {
194 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
195 write!(f, "{}({}, {})", $friendly_name, self.x, self.y)
196 }
197 }
198 };
199}
200
201#[macro_export]
217macro_rules! define_xy_dimensions {
218 ($name:ident, $var_type:ty, $friendly_name:expr, $invalid_zero_value:expr, $doc_string:expr) => {
219 #[doc = $doc_string]
220 #[derive(Clone, Debug, PartialEq, Copy, Hash, Eq, serde::Serialize, serde::Deserialize)]
221 pub struct $name {
222 pub width: $var_type,
223 pub height: $var_type,
224 }
225
226 impl $name {
227 pub fn new(x: $var_type, y: $var_type) -> Result<Self, FeagiDataError> {
228 if x == $invalid_zero_value || y == $invalid_zero_value {
229 return Err(FeagiDataError::BadParameters(format!(
230 "Value cannot be {:?} in a {:?}!",
231 $invalid_zero_value, $friendly_name
232 )));
233 }
234 Ok(Self {
235 width: x,
236 height: y,
237 })
238 }
239 }
240
241 impl std::fmt::Display for $name {
242 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
243 write!(f, "{}<{}, {}>", $friendly_name, self.width, self.height)
244 }
245 }
246
247 impl From<$name> for ($var_type, $var_type) {
248 fn from(value: $name) -> Self {
249 (value.width, value.height)
250 }
251 }
252
253 impl TryFrom<($var_type, $var_type)> for $name {
254 type Error = FeagiDataError;
255 fn try_from(value: ($var_type, $var_type)) -> Result<Self, Self::Error> {
256 if value.0 == $invalid_zero_value {
257 return Err(FeagiDataError::BadParameters(format!(
258 "X value cannot be zero!"
259 )));
260 }
261 if value.1 == $invalid_zero_value {
262 return Err(FeagiDataError::BadParameters(format!(
263 "Y value cannot be zero!"
264 )));
265 }
266 Ok(Self {
267 width: value.0,
268 height: value.1,
269 })
270 }
271 }
272 };
273}
274
275#[macro_export]
294macro_rules! define_xyz_coordinates {
295 ($name:ident, $var_type:ty, $friendly_name:expr, $doc_string:expr) => {
296 #[doc = $doc_string]
297 #[derive(Clone, Debug, PartialEq, Eq, Hash, Copy, serde::Serialize, serde::Deserialize)]
298 pub struct $name {
299 pub x: $var_type,
300 pub y: $var_type,
301 pub z: $var_type,
302 }
303
304 impl $name {
305 pub fn new(x: $var_type, y: $var_type, z: $var_type) -> Self {
306 Self { x, y, z }
307 }
308 }
309
310 impl From<$name> for ($var_type, $var_type, $var_type) {
311 fn from(value: $name) -> Self {
312 (value.x, value.y, value.z)
313 }
314 }
315
316 impl From<($var_type, $var_type, $var_type)> for $name {
317 fn from(value: ($var_type, $var_type, $var_type)) -> Self {
318 $name::new(value.0, value.1, value.2)
319 }
320 }
321
322 impl std::fmt::Display for $name {
323 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
324 write!(f, "{}({}, {}, {})", $friendly_name, self.x, self.y, self.z)
325 }
326 }
327 };
328}
329
330#[macro_export]
348macro_rules! define_xyz_dimensions {
349 ($name:ident, $var_type:ty, $friendly_name:expr, $invalid_zero_value:expr, $doc_string:expr) => {
350 #[doc = $doc_string]
351 #[derive(Clone, Debug, PartialEq, Eq, Hash, Copy, serde::Serialize, serde::Deserialize)]
352 pub struct $name {
353 pub width: $var_type,
354 pub height: $var_type,
355 pub depth: $var_type,
356 }
357
358 impl $name {
359 pub fn new(x: $var_type, y: $var_type, z: $var_type) -> Result<Self, FeagiDataError> {
360 if x == $invalid_zero_value || y == $invalid_zero_value || z == $invalid_zero_value
361 {
362 return Err(FeagiDataError::BadParameters(format!(
363 "Value cannot be {:?} in a {:?}!",
364 $invalid_zero_value, $friendly_name
365 )));
366 }
367 Ok(Self {
368 width: x,
369 height: y,
370 depth: z,
371 })
372 }
373
374 pub fn from_tuple(
376 tuple: ($var_type, $var_type, $var_type),
377 ) -> Result<Self, FeagiDataError> {
378 Self::new(tuple.0, tuple.1, tuple.2)
379 }
380
381 pub fn to_tuple(&self) -> ($var_type, $var_type, $var_type) {
383 (self.width, self.height, self.depth)
384 }
385
386 pub fn number_elements(&self) -> $var_type {
388 self.width * self.height * self.depth
389 }
390
391 pub fn volume(&self) -> $var_type {
393 self.number_elements()
394 }
395
396 pub fn total_voxels(&self) -> $var_type {
398 self.number_elements()
399 }
400
401 pub fn contains(&self, pos: ($var_type, $var_type, $var_type)) -> bool {
403 pos.0 < self.width && pos.1 < self.height && pos.2 < self.depth
404 }
405 }
406
407 impl std::fmt::Display for $name {
408 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
409 write!(
410 f,
411 "{}<{}, {}, {}>",
412 $friendly_name, self.width, self.height, self.depth
413 )
414 }
415 }
416
417 impl From<$name> for ($var_type, $var_type, $var_type) {
418 fn from(value: $name) -> Self {
419 (value.width, value.height, value.depth)
420 }
421 }
422
423 impl TryFrom<($var_type, $var_type, $var_type)> for $name {
424 type Error = FeagiDataError;
425 fn try_from(value: ($var_type, $var_type, $var_type)) -> Result<Self, Self::Error> {
426 if value.0 == $invalid_zero_value {
427 return Err(FeagiDataError::BadParameters(format!(
428 "X value cannot be zero!"
429 )));
430 }
431 if value.1 == $invalid_zero_value {
432 return Err(FeagiDataError::BadParameters(format!(
433 "Y value cannot be zero!"
434 )));
435 }
436 if value.2 == $invalid_zero_value {
437 return Err(FeagiDataError::BadParameters(format!(
438 "Z value cannot be zero!"
439 )));
440 }
441 Ok(Self {
442 width: value.0,
443 height: value.1,
444 depth: value.2,
445 })
446 }
447 }
448 };
449}
450
451#[macro_export]
467macro_rules! define_xyz_mapping {
468 ($XYZ_a:ident, $XYZ_b:ident) => {
469 impl From<$XYZ_a> for $XYZ_b {
470 fn from(a: $XYZ_a) -> Self {
471 $XYZ_b::new(a.width, a.height, a.depth).unwrap()
472 }
473 }
474 impl From<$XYZ_b> for $XYZ_a {
475 fn from(b: $XYZ_b) -> Self {
476 $XYZ_a::new(b.width, b.height, b.depth).unwrap()
477 }
478 }
479 };
480}
481
482#[macro_export]
499macro_rules! define_xyz_dimension_range {
500 ($name:ident, $var_type:ty, $coordinate_type:ty, $friendly_name:expr, $doc:expr) => {
501 #[doc = $doc]
502 #[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
503 pub struct $name {
504 pub width: std::ops::Range<$var_type>,
505 pub height: std::ops::Range<$var_type>,
506 pub depth: std::ops::Range<$var_type>,
507 }
508
509 impl $name {
510 pub fn new(
512 x: std::ops::Range<$var_type>,
513 y: std::ops::Range<$var_type>,
514 z: std::ops::Range<$var_type>,
515 ) -> Result<Self, FeagiDataError> {
516 Ok($name {
517 width: x,
518 height: y,
519 depth: z,
520 })
521 }
522
523 pub fn verify_coordinate_within_range(
525 &self,
526 coordinate: &$coordinate_type,
527 ) -> Result<(), FeagiDataError> {
528 if self.width.contains(&coordinate.width)
529 && self.height.contains(&coordinate.height)
530 && self.depth.contains(&coordinate.depth)
531 {
532 return Ok(());
533 }
534 Err(FeagiDataError::BadParameters(format!(
535 "Coordinate {:?} is not contained by this given range of {:?}!",
536 coordinate, self
537 )))
538 }
539 }
540
541 impl std::fmt::Display for $name {
542 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
543 write!(
544 f,
545 "{}<{:?}, {:?}, {:?}>",
546 $friendly_name, self.width, self.height, self.depth
547 )
548 }
549 }
550 };
551}
552
553