modes:mod: refactor Hand

Hand now requires Ord to be implemented, and test_footstool is a bit
more precise than test_footstool_non_reflexivity.
This commit is contained in:
2026-04-04 04:13:51 +01:00
committed by oreodave
parent fa6ce21fce
commit c2842c02e4

View File

@@ -9,39 +9,53 @@ pub enum Footstool {
Full,
}
pub trait Hand {
/** Given two instances of a Hand (`self` and `other`), verify if `self`
footstools `other`.
*/
fn footstool(&self, other: &Self) -> Footstool;
pub trait Hand: Ord {
// Only need to implement is_proper.
fn is_proper(&self) -> bool;
fn is_improper(&self) -> bool {
!self.is_proper()
}
/** Given two instances of a Hand (`self` and `other`), verify if `self`
footstools `other`.
*/
fn footstool(&self, other: &Self) -> Footstool;
}
#[cfg(test)]
mod tests {
use std::fmt::Display;
use super::*;
/** Given two hands, assert that their footstool condition is non-reflexive.
Return the results of the two footstool checks (x on y, y on x).
/** Given two hands, assert that applying a footstool both ways fits a
recognised pattern. Return the results of the two footstool checks (x on y,
y on x).
*/
pub fn test_footstool_non_reflexivity<T: Hand + Copy>(
x: &T,
y: &T,
) -> (Footstool, Footstool) {
pub fn test_footstool<T>(x: &T, y: &T) -> (Footstool, Footstool)
where
T: Hand + Copy + Display,
{
let res1 = x.footstool(y);
let res2 = y.footstool(x);
matches!(
(res1, res2),
(Footstool::None, Footstool::None)
assert!(
match (res1, res2) {
// Default patterns we'd expect
(Footstool::Half, Footstool::None)
| (Footstool::None, Footstool::Half)
| (Footstool::Half, Footstool::None)
| (Footstool::Full, Footstool::Full)
| (Footstool::None, Footstool::None)
=> true,
// Patterns that require an exact examination to be certain
(Footstool::Full, Footstool::Full) => x == y,
_ => true,
},
"Expected footstool on {}, {} ({:?}, {:?}) to match a recognised pattern",
x,
y,
res1,
res2
);
(res1, res2)
}