1use super::error::DepthError;
3use std::{
4 fmt::Display,
5 ops::{Add, Deref, Sub},
6};
7
8#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
10pub struct Depth(u8);
11
12impl Depth {
13 pub const ZERO: Self = Self(0);
15
16 pub const ONE: Self = Self(1);
18
19 pub fn increment(&mut self) -> Result<(), DepthError> {
22 *self = (*self + 1)?;
23 Ok(())
24 }
25
26 pub fn decrement(&mut self) -> Result<(), DepthError> {
29 *self = (*self - 1)?;
30 Ok(())
31 }
32}
33
34macro_rules! impl_add {
35 ($t:ty) => {
36 impl Add<u8> for $t {
37 type Output = Result<Depth, DepthError>;
38
39 #[inline]
40 fn add(self, rhs: u8) -> Self::Output {
41 self.0
42 .checked_add(rhs)
43 .ok_or(DepthError::AboveLimit(u8::MAX as usize))
44 .map(Depth)
45 }
46 }
47 };
48}
49
50macro_rules! impl_sub {
51 ($t:ty) => {
52 impl Sub<u8> for $t {
53 type Output = Result<Depth, DepthError>;
54
55 #[inline]
56 fn sub(self, rhs: u8) -> Self::Output {
57 self.0.checked_sub(rhs).ok_or(DepthError::BelowZero).map(Depth)
58 }
59 }
60 };
61}
62
63impl_add!(Depth);
64impl_add!(&Depth);
65impl_add!(&mut Depth);
66
67impl_sub!(Depth);
68impl_sub!(&Depth);
69impl_sub!(&mut Depth);
70
71impl Display for Depth {
72 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
73 self.0.fmt(f)
74 }
75}
76
77impl Deref for Depth {
78 type Target = u8;
79
80 fn deref(&self) -> &Self::Target {
81 &self.0
82 }
83}