feat: Replace panic! by Result

This commit is contained in:
Guilhem 2022-06-17 16:56:45 +02:00
parent ae61a25c05
commit 869286ef9b

View File

@ -26,21 +26,31 @@ pub struct Teeth {
}
impl Teeth {
pub fn new(number: u8, quadrant: QuadrantKind, permanent: bool) -> Teeth {
Teeth::check_teeth_number(number, permanent);
pub fn new(number: u8, quadrant: QuadrantKind, permanent: bool) -> Result<Teeth, String> {
if let Err(err) = Teeth::check_teeth_number(number, permanent) {
return Err(err);
}
Teeth {
Ok(Teeth {
number,
quadrant,
permanent,
}
})
}
fn check_teeth_number(number: u8, permanent: bool) {
fn check_teeth_number(number: u8, permanent: bool) -> Result<(), String> {
if permanent && (number < 1 || number > 8) {
panic!("Permanent teeth {} should be in range [1; 8]", number)
Err(format!(
"Permanent teeth {} should be in range [1; 8]",
number
))
} else if !permanent && (number < 1 || number > 5) {
panic!("Primary teeth {} should be in range [1; 5]", number)
Err(format!(
"Primary teeth {} should be in range [1; 5]",
number
))
} else {
Ok(())
}
}
@ -52,9 +62,9 @@ impl Teeth {
}
}
pub fn from_iso(value: &str) -> Self {
pub fn from_iso(value: &str) -> Result<Self, String> {
if value.len() != 2 {
panic!("{} is not a valid ISO dental notation", value);
return Err(format!("{} is not a valid ISO dental notation", value));
}
let mut char_iter = value.chars();
let (quadrant, permanent) = match char_iter.next().unwrap() {
@ -66,22 +76,24 @@ impl Teeth {
'6' => (QuadrantKind::TopRight, false),
'7' => (QuadrantKind::BottomRight, false),
'8' => (QuadrantKind::BottomLeft, false),
x => panic!("Quadrant value {} not included in range [1; 8]", x),
x => return Err(format!("Quadrant value {} not included in range [1; 8]", x)),
};
let teeth_string = char_iter.next().unwrap();
let teeth_number_option = teeth_string.to_digit(10);
if teeth_number_option.is_none() {
panic!("{} is not a number", teeth_string)
return Err(format!("{} is not a number", teeth_string));
}
let number = teeth_number_option.unwrap() as u8;
Teeth::check_teeth_number(number, permanent);
Teeth {
if let Err(err) = Teeth::check_teeth_number(number, permanent) {
return Err(err);
}
Ok(Teeth {
quadrant,
permanent,
number,
}
})
}
pub fn to_iso(&self) -> String {
@ -98,7 +110,7 @@ impl Teeth {
quadrant_number.to_string() + &self.number.to_string()
}
pub fn from_uns(value: &str) -> Self {
pub fn from_uns(value: &str) -> Result<Self, String> {
let number_value_option = value.parse::<u8>();
let mut permanent = false;
let uns = if number_value_option.is_ok() {
@ -109,12 +121,12 @@ impl Teeth {
};
if permanent && (uns < 1 || uns > 32) {
panic!(
return Err(format!(
"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]");
return Err(format!("UNS primary teeth has to be in range [A; T]"));
}
let max = Teeth::quadrant_max(permanent);
let quadrant = match ((uns - 1) / max) + 1 {
@ -122,19 +134,21 @@ impl Teeth {
2 => QuadrantKind::TopRight,
3 => QuadrantKind::BottomRight,
4 => QuadrantKind::BottomLeft,
_ => panic!("UNS teeth value not in range"),
_ => return Err(format!("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 {
if let Err(err) = Teeth::check_teeth_number(number, permanent) {
return Err(err);
}
Ok(Teeth {
quadrant,
number,
permanent,
}
})
}
pub fn to_uns(&self) -> String {
@ -153,19 +167,24 @@ impl Teeth {
}
}
pub fn from_alphanumeric(value: &str) -> Self {
pub fn from_alphanumeric(value: &str) -> Result<Self, String> {
if value.len() != 3 {
panic!("{} is not a valid alphanumeric dental notation", value);
return Err(format!(
"{} is not a valid alphanumeric dental notation",
value
));
}
let quadrant = match &value[0..2] {
"UL" => QuadrantKind::TopLeft,
"UR" => QuadrantKind::TopRight,
"LR" => QuadrantKind::BottomRight,
"LL" => QuadrantKind::BottomLeft,
x => panic!(
"Quadrant value {} not a valid value (accepted: ['UL', 'UR', 'LR', 'LL'])",
x
),
x => {
return Err(format!(
"Quadrant value {} not a valid value (accepted: ['UL', 'UR', 'LR', 'LL'])",
x
))
}
};
let teeth_string = &value[2..3];
@ -184,17 +203,21 @@ impl Teeth {
"C" => (3, false),
"D" => (4, false),
"E" => (5, false),
x => panic!(
"Number value {} not a valid value (accepted: [1; 8] and ['A'; 'E'])",
x
),
x => {
return Err(format!(
"Number value {} not a valid value (accepted: [1; 8] and ['A'; 'E'])",
x
))
}
};
Teeth::check_teeth_number(number, permanent);
Teeth {
if let Err(err) = Teeth::check_teeth_number(number, permanent) {
return Err(err);
}
Ok(Teeth {
quadrant,
permanent,
number,
}
})
}
pub fn to_alphanumeric(&self) -> String {
@ -236,7 +259,8 @@ mod test {
($name:ident, $func:ident, $value:expr, $quadrant:expr,$number:expr, $permanent:expr) => {
#[test]
fn $name() {
let teeth = Teeth::$func($value);
let teeth = Teeth::$func($value).unwrap();
assert_eq!(teeth.quadrant, $quadrant);
assert_eq!(teeth.number, $number);
assert_eq!(teeth.permanent, $permanent);
@ -247,9 +271,8 @@ mod test {
macro_rules! from_fail {
($name:ident, $func:ident, $value:expr) => {
#[test]
#[should_panic]
fn $name() {
Teeth::$func($value);
assert!(Teeth::$func($value).is_err());
}
};
}