use std::sync::Arc;
use super::Document;
use crate::prelude::*;
const LAWSUIT_NUMBER_LENGTH: usize = 20;
#[derive(PartialEq, Eq, Hash)]
pub struct LawsuitNumber(Arc<str>);
impl AsRef<str> for LawsuitNumber {
fn as_ref(&self) -> &str {
self.0.as_ref()
}
}
impl Document for LawsuitNumber {
fn new(document: impl Into<Arc<str>>) -> Result<Self> {
let document: Arc<str> = document
.into()
.chars()
.filter(char::is_ascii_digit)
.collect::<String>()
.into();
if Self::validate(Arc::clone(&document)) {
Ok(Self(document))
} else {
Err(Error::ParseError(document))
}
}
fn validate(document: impl Into<Arc<str>>) -> bool {
let document: Arc<str> = document.into();
let document = document.replace(|x: char| !x.is_ascii_digit(), "");
if document.len() != LAWSUIT_NUMBER_LENGTH {
return false;
}
let seed = format!("{}{}", &document[..7], &document[9..]);
let r1 = seed[..7].parse::<u32>().unwrap() % 97;
let r2 = format!("{r1}{}", &seed[7..14]).parse::<u32>().unwrap() % 97;
let r3 = format!("{r2}{}00", &seed[14..]).parse::<u32>().unwrap() % 97;
let digits = 98 - r3;
document[7..9].parse::<u32>().unwrap() == digits
}
fn document_name(&self) -> &'static str {
"lawsuit_number"
}
}