use crate::domain::errors::ErroSerie; use regex::Regex; use std::sync::OnceLock; static REGEX_SERIE: OnceLock = OnceLock::new(); fn regex_serie() -> &'static Regex { REGEX_SERIE.get_or_init(|| Regex::new(r"^[0-9]{1,3}$").expect("Regex de série inválida")) } /// Valida e normaliza uma série. /// Retorna `Ok(serie_normalizada)` ou `Err(ErroSerie)`. pub fn validar_serie(s: &str) -> Result { let trimmed = s.trim(); if trimmed.is_empty() { return Err(ErroSerie::Vazia); } if regex_serie().is_match(trimmed) { Ok(trimmed.to_string()) } else { Err(ErroSerie::Invalida(trimmed.to_string())) } } #[cfg(test)] mod tests { use super::*; #[test] fn serie_valida_simples() { assert!(validar_serie("1").is_ok()); assert!(validar_serie("01").is_ok()); assert!(validar_serie("001").is_ok()); assert!(validar_serie("999").is_ok()); } #[test] fn serie_com_espacos_e_valida() { assert!(validar_serie(" 1 ").is_ok()); } #[test] fn serie_invalida_letras() { assert!(validar_serie("ABC").is_err()); assert!(validar_serie("1A").is_err()); } #[test] fn serie_invalida_quatro_digitos() { assert!(validar_serie("1234").is_err()); } #[test] fn serie_vazia() { assert!(matches!(validar_serie(""), Err(ErroSerie::Vazia))); assert!(matches!(validar_serie(" "), Err(ErroSerie::Vazia))); } }