Skip to main content

fiscal_core/
state_codes.rs

1//! Brazilian state IBGE code lookup tables and helper functions.
2//!
3//! Two static maps are provided:
4//! - [`STATE_IBGE_CODES`] — two-letter UF abbreviation → IBGE numeric `cUF` code.
5//! - [`IBGE_TO_UF`] — IBGE numeric code → two-letter UF abbreviation (reverse).
6//!
7//! Use [`get_state_code`] and [`get_state_by_code`] for ergonomic access
8//! with proper error handling.
9
10use std::collections::HashMap;
11use std::sync::LazyLock;
12
13use crate::FiscalError;
14
15/// Lazy-initialised map from two-letter UF abbreviation to IBGE numeric state code (`cUF`).
16///
17/// Contains all 26 Brazilian states plus the Federal District (DF).
18///
19/// # Examples
20///
21/// ```
22/// use fiscal_core::state_codes::STATE_IBGE_CODES;
23/// assert_eq!(STATE_IBGE_CODES.get("PR"), Some(&"41"));
24/// assert_eq!(STATE_IBGE_CODES.get("SP"), Some(&"35"));
25/// ```
26pub static STATE_IBGE_CODES: LazyLock<HashMap<&'static str, &'static str>> = LazyLock::new(|| {
27    HashMap::from([
28        ("AC", "12"),
29        ("AL", "27"),
30        ("AP", "16"),
31        ("AM", "13"),
32        ("BA", "29"),
33        ("CE", "23"),
34        ("DF", "53"),
35        ("ES", "32"),
36        ("GO", "52"),
37        ("MA", "21"),
38        ("MT", "51"),
39        ("MS", "50"),
40        ("MG", "31"),
41        ("PA", "15"),
42        ("PB", "25"),
43        ("PR", "41"),
44        ("PE", "26"),
45        ("PI", "22"),
46        ("RJ", "33"),
47        ("RN", "24"),
48        ("RS", "43"),
49        ("RO", "11"),
50        ("RR", "14"),
51        ("SC", "42"),
52        ("SP", "35"),
53        ("SE", "28"),
54        ("TO", "17"),
55    ])
56});
57
58/// Lazy-initialised reverse map from IBGE numeric state code to two-letter UF abbreviation.
59///
60/// # Examples
61///
62/// ```
63/// use fiscal_core::state_codes::IBGE_TO_UF;
64/// assert_eq!(IBGE_TO_UF.get("41"), Some(&"PR"));
65/// ```
66pub static IBGE_TO_UF: LazyLock<HashMap<&'static str, &'static str>> = LazyLock::new(|| {
67    STATE_IBGE_CODES
68        .iter()
69        .map(|(&uf, &code)| (code, uf))
70        .collect()
71});
72
73/// Get the IBGE numeric code for a state abbreviation.
74///
75/// # Errors
76///
77/// Returns [`FiscalError::InvalidStateCode`] if `uf` is not a known
78/// Brazilian state abbreviation.
79pub fn get_state_code(uf: &str) -> Result<&'static str, FiscalError> {
80    STATE_IBGE_CODES
81        .get(uf)
82        .copied()
83        .ok_or_else(|| FiscalError::InvalidStateCode(uf.to_string()))
84}
85
86/// Get the UF abbreviation for an IBGE numeric code.
87///
88/// # Errors
89///
90/// Returns [`FiscalError::InvalidStateCode`] if `code` is not a known
91/// IBGE numeric state code.
92pub fn get_state_by_code(code: &str) -> Result<&'static str, FiscalError> {
93    IBGE_TO_UF
94        .get(code)
95        .copied()
96        .ok_or_else(|| FiscalError::InvalidStateCode(code.to_string()))
97}