balanced_direction/
ternary.rs

1use crate::Balance;
2use balanced_ternary::Digit;
3use core::ops::{BitAnd, BitOr, BitXor};
4
5impl BitAnd for Balance {
6    type Output = Self;
7    fn bitand(self, rhs: Self) -> Self::Output {
8        let (x1, y1) = self.to_ternary_pair();
9        let (x2, y2) = rhs.to_ternary_pair();
10        Balance::from_ternary_pair(x1 & x2, y1 & y2)
11    }
12}
13
14impl BitOr for Balance {
15    type Output = Self;
16    fn bitor(self, rhs: Self) -> Self::Output {
17        let (x1, y1) = self.to_ternary_pair();
18        let (x2, y2) = rhs.to_ternary_pair();
19        Balance::from_ternary_pair(x1 | x2, y1 | y2)
20    }
21}
22
23impl BitXor for Balance {
24    type Output = Self;
25    fn bitxor(self, rhs: Self) -> Self::Output {
26        let (x1, y1) = self.to_ternary_pair();
27        let (x2, y2) = rhs.to_ternary_pair();
28        Balance::from_ternary_pair(x1 ^ x2, y1 ^ y2)
29    }
30}
31
32impl Balance {
33    /// Converts the `Balance` position into a pair of ternary digits.
34    ///
35    /// # Returns
36    ///
37    /// A tuple containing two `Digit` values. The first element represents
38    /// the x-coordinate and the second represents the y-coordinate of the `Balance`
39    /// position in the ternary numeral system.
40    ///
41    /// The `Digit` values can range from `Neg` (-1), `Zero` (0), to `Pos` (1),
42    /// matching the 3x3 balanced grid's coordinate representation.
43    ///
44    /// # Examples
45    ///
46    /// ```
47    /// use balanced_direction::Balance;
48    /// use balanced_ternary::Digit;
49    ///
50    /// let balance = Balance::Top;
51    /// assert_eq!(balance.to_ternary_pair(), (Digit::Zero, Digit::Neg));
52    ///
53    /// let balance = Balance::Right;
54    /// assert_eq!(balance.to_ternary_pair(), (Digit::Pos, Digit::Zero));
55    /// ```
56    pub fn to_ternary_pair(self) -> (Digit, Digit) {
57        (Digit::from_i8(self.x()), Digit::from_i8(self.y()))
58    }
59
60    /// Creates a `Balance` instance from a pair of ternary digits.
61    ///
62    /// # Arguments
63    ///
64    /// * `a` - A `Digit` representing the x-coordinate in the ternary numeral system.
65    /// * `b` - A `Digit` representing the y-coordinate in the ternary numeral system.
66    ///
67    /// # Returns
68    ///
69    /// A new `Balance` instance corresponding to the provided ternary coordinates.
70    ///
71    /// The values of `a` and `b` should be valid ternary digits within the range of:
72    /// - `Neg` (-1), `Zero` (0), and `Pos` (1).
73    ///
74    /// This allows for mapping coordinates within the 3x3 grid system used by the `Balance` enum, ensuring
75    /// that any valid pair of ternary digits maps directly to a specific `Balance` position.
76    ///
77    /// # Examples
78    ///
79    /// ```
80    /// use balanced_direction::Balance;
81    /// use balanced_ternary::Digit;
82    ///
83    /// let balance = Balance::from_ternary_pair(Digit::Zero, Digit::Neg);
84    /// assert_eq!(balance, Balance::Top);
85    ///
86    /// let balance = Balance::from_ternary_pair(Digit::Pos, Digit::Zero);
87    /// assert_eq!(balance, Balance::Right);
88    /// ```
89    pub fn from_ternary_pair(a: Digit, b: Digit) -> Self {
90        Self::from_vector(a.to_i8(), b.to_i8())
91    }
92}