use super::error::{Error, ErrorKind};
use anomaly::{fail, format_err};
use serde::{Deserialize, Serialize};
use std::{
fmt::{self, Display},
str::FromStr,
};
const NUM_DIGITS: usize = 10;
#[derive(Copy, Clone, Debug, Deserialize, Eq, Hash, PartialEq, PartialOrd, Ord, Serialize)]
pub struct Number(u32);
impl Display for Number {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:0width$}", self.0, width = NUM_DIGITS)
}
}
impl FromStr for Number {
type Err = Error;
fn from_str(s: &str) -> Result<Number, Error> {
if s.len() == NUM_DIGITS {
let number = s.parse::<u32>().map_err(|_| {
format_err!(ErrorKind::InvalidData, "error parsing serial number: {}", s)
})?;
Ok(Number(number))
} else {
fail!(
ErrorKind::WrongLength,
"invalid serial number length (expected {}, got {}): '{}'",
NUM_DIGITS,
s.len(),
s
);
}
}
}