From 1298d1ae865bd7ef13366dd6ba4205791c6aca49 Mon Sep 17 00:00:00 2001 From: Guilhem Date: Wed, 15 Jun 2022 17:21:06 +0200 Subject: [PATCH] feat: Add from_uns & to_uns --- src/lib.rs | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 913ed4d..add1d85 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -89,6 +89,71 @@ impl Teeth { }; quadrant_number.to_string() + &self.number.to_string() } + + pub fn from_uns(value: &str) -> Self { + let number_value_option = value.parse::(); + let mut permanent = false; + let uns = if number_value_option.is_ok() { + permanent = true; + number_value_option.unwrap() + } else { + (value.chars().next().expect("No value available") as i32 - 64) as u8 + }; + + if permanent && (uns < 1 || uns > 32) { + panic!( + "UNS permanent teeth has to be in range [1; 32] (currently {})", + uns + ); + } else if !permanent && (uns < 1 || uns > 20) { + panic!("UNS primary teeth has to be in range [A; T]"); + } + let max = Teeth::quadrant_max(permanent); + let quadrant = match ((uns - 1) / max) + 1 { + 1 => QuadrantKind::TopLeft, + 2 => QuadrantKind::TopRight, + 3 => QuadrantKind::BottomRight, + 4 => QuadrantKind::BottomLeft, + _ => panic!("UNS teeth value not in range"), + }; + let number = if quadrant == QuadrantKind::TopRight || quadrant == QuadrantKind::BottomLeft { + ((uns - 1) % max) + 1 + } else { + max - ((uns - 1) % max) + }; + Teeth::check_teeth_number(number, permanent); + Teeth { + quadrant, + number, + permanent, + } + } + + pub fn to_uns(&self) -> String { + let max = Teeth::quadrant_max(self.permanent); + let value: u8 = match (&self.quadrant, self.number) { + (QuadrantKind::TopLeft, x) => x, + (QuadrantKind::TopRight, x) => x + max, + (QuadrantKind::BottomRight, x) => x + max * 2, + (QuadrantKind::BottomLeft, x) => x + max * 3, + }; + + if self.permanent { + value.to_string() + } else { + ((value + 64) as char).to_string() + } + } + + fn quadrant_max(permanent: bool) -> u8 { + if permanent { + 8 + } else { + 5 + } + } +} + #[cfg(test)] mod test { use super::*; @@ -179,4 +244,79 @@ mod test { from_iso_fail!(from_iso_fail_76, "76"); from_iso_fail!(from_iso_fail_80, "80"); from_iso_fail!(from_iso_fail_86, "86"); + + macro_rules! to_uns { + ($name:ident, $quadrant:expr,$number:expr, $permanent:expr, $uns:expr) => { + #[test] + fn $name() { + let teeth = Teeth { + quadrant: $quadrant, + number: $number, + permanent: $permanent, + }; + assert_eq!(teeth.to_uns(), $uns); + } + }; + } + + macro_rules! from_uns { + ($name:ident, $uns:expr, $quadrant:expr,$number:expr, $permanent:expr) => { + #[test] + fn $name() { + let teeth = Teeth::from_uns($uns); + assert_eq!(teeth.quadrant, $quadrant); + assert_eq!(teeth.number, $number); + assert_eq!(teeth.permanent, $permanent); + } + }; + } + + macro_rules! from_uns_fail { + ($name:ident, $uns:expr) => { + #[test] + #[should_panic] + fn $name() { + Teeth::from_uns($uns); + } + }; + } + + to_uns!(to_uns_1, QuadrantKind::TopLeft, 1, true, "1"); + to_uns!(to_uns_8, QuadrantKind::TopLeft, 8, true, "8"); + to_uns!(to_uns_9, QuadrantKind::TopRight, 1, true, "9"); + to_uns!(to_uns_16, QuadrantKind::TopRight, 8, true, "16"); + to_uns!(to_uns_17, QuadrantKind::BottomRight, 1, true, "17"); + to_uns!(to_uns_24, QuadrantKind::BottomRight, 8, true, "24"); + to_uns!(to_uns_25, QuadrantKind::BottomLeft, 1, true, "25"); + to_uns!(to_uns_32, QuadrantKind::BottomLeft, 8, true, "32"); + to_uns!(to_uns_a, QuadrantKind::TopLeft, 1, false, "A"); + to_uns!(to_uns_e, QuadrantKind::TopLeft, 5, false, "E"); + to_uns!(to_uns_f, QuadrantKind::TopRight, 1, false, "F"); + to_uns!(to_uns_j, QuadrantKind::TopRight, 5, false, "J"); + to_uns!(to_uns_k, QuadrantKind::BottomRight, 1, false, "K"); + to_uns!(to_uns_o, QuadrantKind::BottomRight, 5, false, "O"); + to_uns!(to_uns_p, QuadrantKind::BottomLeft, 1, false, "P"); + to_uns!(to_uns_t, QuadrantKind::BottomLeft, 5, false, "T"); + + from_uns!(from_uns_8, "8", QuadrantKind::TopLeft, 1, true); + from_uns!(from_uns_1, "1", QuadrantKind::TopLeft, 8, true); + from_uns!(from_uns_9, "9", QuadrantKind::TopRight, 1, true); + from_uns!(from_uns_16, "16", QuadrantKind::TopRight, 8, true); + from_uns!(from_uns_24, "24", QuadrantKind::BottomRight, 1, true); + from_uns!(from_uns_17, "17", QuadrantKind::BottomRight, 8, true); + from_uns!(from_uns_25, "25", QuadrantKind::BottomLeft, 1, true); + from_uns!(from_uns_32, "32", QuadrantKind::BottomLeft, 8, true); + from_uns!(from_uns_e, "E", QuadrantKind::TopLeft, 1, false); + from_uns!(from_uns_a, "A", QuadrantKind::TopLeft, 5, false); + from_uns!(from_uns_f, "F", QuadrantKind::TopRight, 1, false); + from_uns!(from_uns_j, "J", QuadrantKind::TopRight, 5, false); + from_uns!(from_uns_o, "O", QuadrantKind::BottomRight, 1, false); + from_uns!(from_uns_k, "K", QuadrantKind::BottomRight, 5, false); + from_uns!(from_uns_p, "P", QuadrantKind::BottomLeft, 1, false); + from_uns!(from_uns_t, "T", QuadrantKind::BottomLeft, 5, false); + + from_uns_fail!(from_uns_fail_0, "0"); + from_uns_fail!(from_uns_fail_33, "33"); + from_uns_fail!(from_uns_fail_at, "@"); + from_uns_fail!(from_uns_fail_u, "U"); }