konduto/types/address/
state.rs

1use crate::impl_nutype_error_conversion;
2use nutype::nutype;
3
4/// Nome do estado/província (máximo 100 caracteres)
5///
6/// Aceita tanto siglas (SP, RJ) quanto nomes completos (São Paulo, Rio de Janeiro)
7///
8/// # Validações
9/// - Não pode ser vazio (após trim)
10/// - Máximo 100 caracteres
11///
12/// # Exemplos
13/// ```
14/// use konduto::State;
15///
16/// let state = State::try_new("SP").unwrap();
17/// assert_eq!(state.as_str(), "SP");
18///
19/// let state = State::try_new("São Paulo").unwrap();
20/// assert_eq!(state.as_str(), "São Paulo");
21/// ```
22#[nutype(
23    sanitize(trim),
24    validate(not_empty, len_char_max = 100),
25    derive(
26        Debug,
27        Clone,
28        PartialEq,
29        Eq,
30        Display,
31        AsRef,
32        Deref,
33        Serialize,
34        Deserialize,
35    )
36)]
37pub struct State(String);
38
39impl State {
40    /// Retorna o nome do estado como string slice (compatibilidade)
41    pub fn as_str(&self) -> &str {
42        self.as_ref()
43    }
44}
45
46impl_nutype_error_conversion!(StateError);
47
48#[cfg(test)]
49mod tests {
50    use super::*;
51
52    #[test]
53    fn test_valid_state() {
54        let state = State::try_new("SP").unwrap();
55        assert_eq!(state.as_str(), "SP");
56    }
57
58    #[test]
59    fn test_state_full_name() {
60        let state = State::try_new("São Paulo").unwrap();
61        assert_eq!(state.as_str(), "São Paulo");
62    }
63
64    #[test]
65    fn test_state_with_whitespace() {
66        let state = State::try_new("  RJ  ").unwrap();
67        assert_eq!(state.as_str(), "RJ");
68    }
69
70    #[test]
71    fn test_empty_state() {
72        let result = State::try_new("");
73        assert!(result.is_err());
74    }
75
76    #[test]
77    fn test_state_too_long() {
78        let long_state = "a".repeat(101);
79        let result = State::try_new(long_state);
80        assert!(result.is_err());
81    }
82}