use std::{
fmt::{Debug, Display},
hash::Hash,
};
use crate::{ARSCodeError, ARSLevel, FederalState};
type ARSCodeResult<T> = Result<T, ARSCodeError>;
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct ARSCode {
ars12: u64,
}
impl ARSCode {
pub const GERMANY: ARSCode = unsafe {
Self::from_raw_unchecked(Self::inner_from_parts(0, 0, 0, 0, 0, 0, ARSLevel::COUNTRY))
};
pub fn new(l: u8, rb: u8, k: u8, v1: u8, v2: u8, g: u16) -> ARSCodeResult<Self> {
if !(0..=16).contains(&l) {
return Err(ARSCodeError::InvalidPartLand { land: l });
}
if rb > 9 {
return Err(ARSCodeError::InvalidPartDistrict { district: rb });
}
if k > 99 {
return Err(ARSCodeError::InvalidPartCounty { county: k });
}
if v1 > 99 {
return Err(ARSCodeError::InvalidPartVG1 { vg1: v1 });
}
if v2 > 99 {
return Err(ARSCodeError::InvalidPartVG2 { vg2: v2 });
}
if g > 999 {
return Err(ARSCodeError::InvalidPartMunicipality { municipality: g });
}
let level = Self::get_level(l, rb, k, v1, v2, g);
Ok(Self {
ars12: Self::inner_from_parts(l, rb, k, v1, v2, g, level),
})
}
const fn inner_from_parts(
l: u8,
rb: u8,
k: u8,
v1: u8,
v2: u8,
g: u16,
level: ARSLevel,
) -> u64 {
(l as u64) << 56
| (rb as u64) << 48
| (k as u64) << 40
| (v1 as u64) << 32
| (v2 as u64) << 24
| (g as u64) << 8
| (level.inner() as u64)
}
pub fn new_common_parent(ars_codes: &[Self]) -> Option<Self> {
match ars_codes.len() {
0 => None,
1 => Some(ars_codes[0].clone()),
_ => {
let mut outer_most_parent = None;
let mut outer_most_parent_level = ARSLevel::MIN;
for ars_code in ars_codes {
if ars_code.level() <= outer_most_parent_level {
outer_most_parent = Some(ars_code);
outer_most_parent_level = ars_code.level();
}
}
let check_containment = |parent: ARSCode| -> bool {
for ars_code in ars_codes {
if !parent.contains(ars_code) {
return false;
}
}
true
};
let mut outer_most_parent = outer_most_parent.unwrap().clone();
if check_containment(outer_most_parent.clone()) {
return Some(outer_most_parent);
}
while let Some(parent) = outer_most_parent.parent() {
if check_containment(parent.clone()) {
return Some(parent);
}
outer_most_parent = parent;
}
None
}
}
}
#[inline]
fn get_level(l: u8, rb: u8, k: u8, v1: u8, v2: u8, g: u16) -> ARSLevel {
if g == 0 {
if v1 == 0 && v2 == 0 {
if k == 0 {
if rb == 0 {
if l == 0 {
ARSLevel::COUNTRY
} else {
ARSLevel::STATE
}
} else {
ARSLevel::DISTRICT
}
} else {
ARSLevel::COUNTY
}
} else {
ARSLevel::ADMIN_ASSOCIATION
}
} else {
ARSLevel::MUNICIPALITY
}
}
pub fn clamp_to_level(&self, level: ARSLevel) -> Self {
if self.level() > level {
match level {
ARSLevel::COUNTRY => ARSCode {
ars12: Self::inner_from_parts(0, 0, 0, 0, 0, 0, ARSLevel::COUNTRY),
},
ARSLevel::STATE => ARSCode {
ars12: Self::inner_from_parts(self.l(), 0, 0, 0, 0, 0, ARSLevel::STATE),
},
ARSLevel::DISTRICT => ARSCode {
ars12: Self::inner_from_parts(
self.l(),
self.rb(),
0,
0,
0,
0,
ARSLevel::DISTRICT,
),
},
ARSLevel::COUNTY => ARSCode {
ars12: Self::inner_from_parts(
self.l(),
self.rb(),
self.k(),
0,
0,
0,
ARSLevel::COUNTY,
),
},
ARSLevel::ADMIN_ASSOCIATION => ARSCode {
ars12: Self::inner_from_parts(
self.l(),
self.rb(),
self.k(),
self.v1(),
self.v2(),
0,
ARSLevel::ADMIN_ASSOCIATION,
),
},
ARSLevel::MUNICIPALITY => ARSCode {
ars12: Self::inner_from_parts(
self.l(),
self.rb(),
self.k(),
self.v1(),
self.v2(),
self.g(),
ARSLevel::MUNICIPALITY,
),
},
_ => unreachable!(),
}
} else {
self.clone()
}
}
pub const unsafe fn from_raw_unchecked(ars12: u64) -> Self {
Self { ars12 }
}
pub fn contains(&self, other: &ARSCode) -> bool {
let self_level = self.level();
let other_level = other.level();
if self_level > other_level {
return false;
}
if self_level == other_level {
return self == other;
}
let mut parent = other.parent();
while let Some(ref other_code) = parent {
if self_level == other_code.level() && self == other_code {
return true;
}
parent = other_code.parent();
}
false
}
pub fn parent(&self) -> Option<ARSCode> {
match self.level() {
ARSLevel::COUNTRY => None,
ARSLevel::STATE => Some(ARSCode {
ars12: Self::inner_from_parts(0, 0, 0, 0, 0, 0, ARSLevel::COUNTRY),
}),
ARSLevel::DISTRICT => Some(ARSCode {
ars12: Self::inner_from_parts(self.l(), 0, 0, 0, 0, 0, ARSLevel::STATE),
}),
ARSLevel::COUNTY => Some(ARSCode {
ars12: Self::inner_from_parts(self.l(), self.rb(), 0, 0, 0, 0, ARSLevel::DISTRICT),
}),
ARSLevel::ADMIN_ASSOCIATION => Some(ARSCode {
ars12: Self::inner_from_parts(
self.l(),
self.rb(),
self.k(),
0,
0,
0,
ARSLevel::COUNTY,
),
}),
ARSLevel::MUNICIPALITY => Some(ARSCode {
ars12: Self::inner_from_parts(
self.l(),
self.rb(),
self.k(),
self.v1(),
self.v2(),
0,
ARSLevel::ADMIN_ASSOCIATION,
),
}),
_ => unreachable!(),
}
}
}
impl ARSCode {
pub fn l(&self) -> u8 {
(self.ars12 >> 56) as u8
}
pub fn rb(&self) -> u8 {
(self.ars12 >> 48) as u8
}
pub fn k(&self) -> u8 {
(self.ars12 >> 40) as u8
}
pub fn v1(&self) -> u8 {
(self.ars12 >> 32) as u8
}
pub fn v2(&self) -> u8 {
(self.ars12 >> 24) as u8
}
pub fn g(&self) -> u16 {
(self.ars12 >> 8) as u16
}
pub fn level(&self) -> ARSLevel {
unsafe { ARSLevel::new_unchecked(self.ars12 as u8) }
}
pub fn federal_sate(&self) -> FederalState {
(*self).into()
}
pub fn inner(&self) -> u64 {
self.ars12
}
pub fn is_empty(&self) -> bool {
self.ars12 == Self::GERMANY.ars12
}
}
impl TryFrom<&str> for ARSCode {
type Error = ARSCodeError;
fn try_from(value: &str) -> Result<Self, Self::Error> {
if value.len() != 9 && value.len() != 12 {
return Err(ARSCodeError::InvalidCodeLength {
erroneous_code: value.into(),
erroneous_code_length: value.len(),
});
}
let l: u8 = value[0..2]
.parse()
.map_err(|_| ARSCodeError::ParsingError {
value: value[0..2].into(),
expected: "u8",
})?;
let rb: u8 = value[2..3]
.parse()
.map_err(|_| ARSCodeError::ParsingError {
value: value[2..3].into(),
expected: "u8",
})?;
let k: u8 = value[3..5]
.parse()
.map_err(|_| ARSCodeError::ParsingError {
value: value[3..5].into(),
expected: "u8",
})?;
let v1: u8 = value[5..7]
.parse()
.map_err(|_| ARSCodeError::ParsingError {
value: value[5..7].into(),
expected: "u8",
})?;
let v2: u8 = value[7..9]
.parse()
.map_err(|_| ARSCodeError::ParsingError {
value: value[7..9].into(),
expected: "u8",
})?;
let g: u16 = if value.len() == 12 {
value[9..12]
.parse()
.map_err(|_| ARSCodeError::ParsingError {
value: value[9..12].into(),
expected: "u8",
})?
} else {
0
};
Self::new(l, rb, k, v1, v2, g)
}
}
impl TryFrom<String> for ARSCode {
type Error = ARSCodeError;
fn try_from(value: String) -> Result<Self, Self::Error> {
value.as_str().try_into()
}
}
impl From<ARSCode> for String {
fn from(value: ARSCode) -> Self {
value.to_string()
}
}
impl Display for ARSCode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{:02}{}{:02}{:02}{:02}{:03}",
self.l(),
self.rb(),
self.k(),
self.v1(),
self.v2(),
self.g()
)
}
}
impl Debug for ARSCode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ARSCode")
.field("ars12", &self.to_string())
.field("level", &self.level())
.finish()
}
}
impl Default for ARSCode {
fn default() -> Self {
Self::GERMANY.clone()
}
}
impl PartialOrd for ARSCode {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
let self_moved = self.ars12 >> 8;
let other_moved = other.ars12 >> 8;
Some(self_moved.cmp(&other_moved))
}
}
impl Ord for ARSCode {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.partial_cmp(other).unwrap()
}
}
#[cfg(feature = "serde")]
pub mod arscode_serde {
use crate::ARSCode;
use serde::{Deserialize, Deserializer, Serialize, Serializer, de};
impl Serialize for ARSCode {
fn serialize<S>(&self, ser: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
ser.serialize_str(&format!("{self}"))
}
}
impl<'de> Deserialize<'de> for ARSCode {
fn deserialize<D>(de: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(de)?;
ARSCode::try_from(s).map_err(de::Error::custom)
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_ars_from_str() {
let code_to_parse = "146260420000";
let ars = code_to_parse.try_into();
assert_eq!(ARSCode::new(14, 6, 26, 04, 20, 0).unwrap(), ars.unwrap());
}
#[test]
fn test_ars_new() {
let ars = ARSCode::new(1, 7, 5, 12, 13, 213).unwrap();
assert_eq!(ars.l(), 1);
assert_eq!(ars.rb(), 7);
assert_eq!(ars.k(), 5);
assert_eq!(ars.v1(), 12);
assert_eq!(ars.v2(), 13);
assert_eq!(ars.g(), 213);
assert_eq!(ars.level(), ARSLevel::MUNICIPALITY);
assert_eq!("017051213213", ars.to_string().as_str());
}
#[test]
fn test_ars_level() {
let country = ARSCode::new(0, 0, 0, 0, 0, 0).unwrap();
let state = ARSCode::new(1, 0, 0, 0, 0, 0).unwrap();
let district = ARSCode::new(1, 1, 0, 0, 0, 0).unwrap();
let county = ARSCode::new(1, 1, 1, 0, 0, 0).unwrap();
let admin_association1 = ARSCode::new(1, 1, 1, 1, 0, 0).unwrap();
let admin_association2 = ARSCode::new(1, 1, 1, 0, 1, 0).unwrap();
let municipality = ARSCode::new(1, 1, 1, 0, 1, 1).unwrap();
assert_eq!(country.level(), ARSLevel::COUNTRY);
assert_eq!(state.level(), ARSLevel::STATE);
assert_eq!(district.level(), ARSLevel::DISTRICT);
assert_eq!(county.level(), ARSLevel::COUNTY);
assert_eq!(admin_association1.level(), ARSLevel::ADMIN_ASSOCIATION);
assert_eq!(admin_association2.level(), ARSLevel::ADMIN_ASSOCIATION);
assert_eq!(municipality.level(), ARSLevel::MUNICIPALITY);
}
#[test]
fn test_ars_level_parent() {
let municipality = ARSCode::new(1, 1, 1, 0, 1, 1).unwrap();
let admin_association = municipality.parent().unwrap();
let county = admin_association.parent().unwrap();
let district = county.parent().unwrap();
let state = district.parent().unwrap();
let country = state.parent().unwrap();
assert_eq!(admin_association, ARSCode::new(1, 1, 1, 0, 1, 0).unwrap());
assert_eq!(county, ARSCode::new(1, 1, 1, 0, 0, 0).unwrap());
assert_eq!(district, ARSCode::new(1, 1, 0, 0, 0, 0).unwrap());
assert_eq!(state, ARSCode::new(1, 0, 0, 0, 0, 0).unwrap());
assert_eq!(country, ARSCode::new(0, 0, 0, 0, 0, 0).unwrap());
assert_eq!(country.parent(), None);
}
#[test]
fn test_ars_level_contains() {
let municipality = ARSCode::new(1, 1, 1, 0, 1, 1).unwrap();
let foreign_municipality = ARSCode::new(2, 1, 1, 0, 1, 1).unwrap();
let admin_association = municipality.parent().unwrap();
let county = admin_association.parent().unwrap();
let district = county.parent().unwrap();
let state = district.parent().unwrap();
let country = state.parent().unwrap();
assert!(admin_association.contains(&municipality));
assert!(!municipality.contains(&admin_association));
assert!(county.contains(&municipality));
assert!(county.contains(&admin_association));
assert!(!county.contains(&district));
assert!(district.contains(&municipality));
assert!(district.contains(&admin_association));
assert!(district.contains(&county));
assert!(!district.contains(&state));
assert!(!district.contains(&country));
assert!(state.contains(&municipality));
assert!(state.contains(&admin_association));
assert!(state.contains(&county));
assert!(state.contains(&district));
assert!(!state.contains(&country));
assert!(!admin_association.contains(&foreign_municipality));
assert!(!county.contains(&foreign_municipality));
assert!(!district.contains(&foreign_municipality));
assert!(!state.contains(&foreign_municipality));
assert!(country.contains(&foreign_municipality));
}
#[test]
fn test_ars_common_parent() {
let codes = vec![
ARSCode::new(1, 1, 1, 1, 1, 1).unwrap(),
ARSCode::new(1, 1, 1, 1, 1, 0).unwrap(),
ARSCode::new(1, 1, 1, 1, 0, 0).unwrap(),
ARSCode::new(1, 1, 1, 0, 0, 0).unwrap(),
];
assert_eq!(
ARSCode::new_common_parent(&codes).unwrap(),
ARSCode::new(1, 1, 1, 0, 0, 0).unwrap()
);
let codes = vec![
ARSCode::new(1, 1, 1, 1, 9, 1).unwrap(),
ARSCode::new(1, 1, 1, 8, 1, 2).unwrap(),
ARSCode::new(1, 1, 1, 6, 1, 4).unwrap(),
ARSCode::new(1, 1, 1, 6, 4, 4).unwrap(),
];
assert_eq!(
ARSCode::new_common_parent(&codes).unwrap(),
ARSCode::new(1, 1, 1, 0, 0, 0).unwrap()
);
let codes = vec![
ARSCode::new(1, 1, 1, 1, 9, 1).unwrap(),
ARSCode::new(1, 2, 1, 8, 1, 2).unwrap(),
ARSCode::new(1, 3, 1, 6, 1, 4).unwrap(),
ARSCode::new(1, 4, 1, 6, 4, 4).unwrap(),
];
assert_eq!(
ARSCode::new_common_parent(&codes).unwrap(),
ARSCode::new(1, 0, 0, 0, 0, 0).unwrap()
);
let codes = vec![
ARSCode::new(1, 1, 1, 1, 1, 1).unwrap(),
ARSCode::new(2, 1, 1, 1, 1, 1).unwrap(),
];
assert_eq!(
ARSCode::new_common_parent(&codes),
Some(ARSCode::new(0, 0, 0, 0, 0, 0).unwrap())
);
}
#[test]
fn test_ars_to_string() {
assert_eq!(
ARSCode::new(1, 7, 5, 12, 13, 213)
.unwrap()
.to_string()
.as_str(),
"017051213213"
);
assert_eq!(
ARSCode::new(1, 7, 5, 2, 3, 203)
.unwrap()
.to_string()
.as_str(),
"017050203203"
);
assert_eq!(
ARSCode::new(1, 7, 5, 2, 3, 0).unwrap().to_string().as_str(),
"017050203000"
);
}
#[test]
fn test_ars_invalid_land() {
let result = ARSCode::new(17, 0, 0, 0, 0, 0);
assert!(result.is_err());
}
#[test]
fn test_ars_invalid_district() {
let result = ARSCode::new(5, 10, 0, 0, 0, 0);
assert!(result.is_err());
}
#[test]
fn test_ars_invalid_county() {
let result = ARSCode::new(5, 3, 100, 0, 0, 0);
assert!(result.is_err());
}
#[test]
fn test_ars_invalid_vg1() {
let result = ARSCode::new(5, 3, 15, 100, 0, 0);
assert!(result.is_err());
}
#[test]
fn test_ars_invalid_vg2() {
let result = ARSCode::new(5, 3, 15, 50, 100, 0);
assert!(result.is_err());
}
#[test]
fn test_ars_invalid_municipality() {
let result = ARSCode::new(5, 3, 15, 8, 4, 1000);
assert!(result.is_err());
}
#[test]
fn test_ars_getters() {
let ars = ARSCode::new(5, 3, 15, 8, 4, 42).unwrap();
assert_eq!(ars.l(), 5);
assert_eq!(ars.rb(), 3);
assert_eq!(ars.k(), 15);
assert_eq!(ars.v1(), 8);
assert_eq!(ars.v2(), 4);
assert_eq!(ars.g(), 42);
}
#[test]
fn test_ars_inner() {
let ars = ARSCode::new(5, 3, 15, 8, 4, 42).unwrap();
let inner = ars.inner();
assert!(inner > 0);
}
#[test]
fn test_ars_is_empty() {
let germany = ARSCode::new(0, 0, 0, 0, 0, 0).unwrap();
assert!(germany.is_empty());
let state = ARSCode::new(5, 0, 0, 0, 0, 0).unwrap();
assert!(!state.is_empty());
let municipality = ARSCode::new(5, 3, 15, 8, 4, 42).unwrap();
assert!(!municipality.is_empty());
}
#[test]
fn test_ars_equality() {
let ars1 = ARSCode::new(5, 3, 15, 8, 4, 42).unwrap();
let ars2 = ARSCode::new(5, 3, 15, 8, 4, 42).unwrap();
let ars3 = ARSCode::new(5, 3, 15, 8, 4, 43).unwrap();
assert_eq!(ars1, ars2);
assert_ne!(ars1, ars3);
}
#[test]
fn test_ars_ordering() {
let ars1 = ARSCode::new(5, 3, 15, 8, 4, 42).unwrap();
let ars2 = ARSCode::new(5, 3, 15, 8, 4, 43).unwrap();
let ars3 = ARSCode::new(5, 3, 15, 9, 4, 1).unwrap();
assert!(ars1 < ars2);
assert!(ars2 > ars1);
assert!(ars1 < ars3);
}
#[test]
fn test_ars_clamp_to_level() {
let _municipality = ARSCode::new(5, 3, 15, 8, 4, 42).unwrap();
let municipality = ARSCode::new(5, 3, 15, 8, 4, 42).unwrap();
let admin = municipality.clamp_to_level(ARSLevel::ADMIN_ASSOCIATION);
assert_eq!(admin.level(), ARSLevel::ADMIN_ASSOCIATION);
assert_eq!(admin.g(), 0);
let county = municipality.clamp_to_level(ARSLevel::COUNTY);
assert_eq!(county.level(), ARSLevel::COUNTY);
assert_eq!(county.g(), 0);
assert_eq!(county.v1(), 0);
assert_eq!(county.v2(), 0);
let state = municipality.clamp_to_level(ARSLevel::STATE);
assert_eq!(state.level(), ARSLevel::STATE);
assert_eq!(state.rb(), 0);
let country = municipality.clamp_to_level(ARSLevel::COUNTRY);
assert_eq!(country.level(), ARSLevel::COUNTRY);
assert_eq!(country.l(), 0);
}
#[test]
fn test_ars_clamp_same_level() {
let municipality = ARSCode::new(5, 3, 15, 8, 4, 42).unwrap();
let clamped = municipality.clamp_to_level(ARSLevel::MUNICIPALITY);
assert_eq!(clamped, municipality);
}
#[test]
fn test_ars_clamp_higher_level() {
let state = ARSCode::new(5, 0, 0, 0, 0, 0).unwrap();
let municipality = ARSCode::new(5, 3, 15, 8, 4, 42).unwrap();
let result = municipality.clamp_to_level(ARSLevel::STATE);
assert_eq!(result, state);
}
#[test]
fn test_ars_try_from_string() {
let ars: ARSCode = "053150804042".try_into().unwrap();
assert_eq!(ars.l(), 5);
assert_eq!(ars.rb(), 3);
assert_eq!(ars.k(), 15);
assert_eq!(ars.v1(), 8);
assert_eq!(ars.v2(), 4);
assert_eq!(ars.g(), 42);
}
#[test]
fn test_ars_try_from_string_9_digits() {
let ars: ARSCode = "053150000".try_into().unwrap();
assert_eq!(ars.l(), 5);
assert_eq!(ars.rb(), 3);
assert_eq!(ars.k(), 15);
assert_eq!(ars.g(), 0);
}
#[test]
fn test_ars_try_from_string_invalid_length() {
let result: Result<ARSCode, _> = "12345".try_into();
assert!(result.is_err());
}
#[test]
fn test_ars_try_from_string_invalid_characters() {
let result: Result<ARSCode, _> = "ABCDEFGHIJKL".try_into();
assert!(result.is_err());
}
#[test]
fn test_ars_try_from_owned_string() {
let s = String::from("053150804042");
let ars: ARSCode = s.try_into().unwrap();
assert_eq!(ars.l(), 5);
assert_eq!(ars.g(), 42);
}
#[test]
fn test_ars_from_string_conversion() {
let ars = ARSCode::new(5, 3, 15, 8, 4, 42).unwrap();
let s: String = ars.into();
assert_eq!(s, "053150804042");
}
#[test]
fn test_ars_default() {
let default_ars = ARSCode::default();
assert!(default_ars.is_empty());
assert_eq!(default_ars.l(), 0);
}
#[test]
fn test_ars_debug() {
let ars = ARSCode::new(5, 3, 15, 8, 4, 42).unwrap();
let debug_str = format!("{:?}", ars);
assert!(debug_str.contains("ARSCode"));
assert!(debug_str.contains("053150804042"));
}
#[test]
fn test_ars_display() {
let ars = ARSCode::new(5, 3, 15, 8, 4, 42).unwrap();
let display_str = format!("{}", ars);
assert_eq!(display_str, "053150804042");
}
#[test]
fn test_ars_federal_state() {
let hamburg = ARSCode::new(2, 0, 0, 0, 0, 0).unwrap();
assert_eq!(hamburg.federal_sate(), FederalState::Hamburg);
let bavaria = ARSCode::new(9, 2, 75, 0, 0, 62).unwrap();
assert_eq!(bavaria.federal_sate(), FederalState::Bavaria);
}
#[test]
fn test_ars_from_federal_state() {
let hamburg = ARSCode::new(2, 0, 0, 0, 0, 0).unwrap();
let from_state: ARSCode = FederalState::Hamburg.into();
assert_eq!(hamburg, from_state);
}
#[test]
fn test_ars_contains_self() {
let ars = ARSCode::new(5, 3, 15, 8, 4, 42).unwrap();
assert!(ars.contains(&ars));
}
#[test]
fn test_ars_common_parent_empty_slice() {
let result = ARSCode::new_common_parent(&[]);
assert_eq!(result, None);
}
#[test]
fn test_ars_common_parent_single_code() {
let ars = ARSCode::new(5, 3, 15, 8, 4, 42).unwrap();
let result = ARSCode::new_common_parent(&[ars]).unwrap();
assert_eq!(result, ars);
}
#[test]
fn test_ars_common_parent_same_codes() {
let ars = ARSCode::new(5, 3, 15, 8, 4, 42).unwrap();
let result = ARSCode::new_common_parent(&[ars, ars]).unwrap();
assert_eq!(result, ars);
}
#[test]
fn test_ars_hash() {
use std::collections::HashSet;
let ars1 = ARSCode::new(5, 3, 15, 8, 4, 42).unwrap();
let ars2 = ARSCode::new(5, 3, 15, 8, 4, 42).unwrap();
let ars3 = ARSCode::new(5, 3, 15, 8, 4, 43).unwrap();
let mut set = HashSet::new();
set.insert(ars1);
set.insert(ars2);
set.insert(ars3);
assert_eq!(set.len(), 2);
}
#[test]
fn test_ars_clone_copy() {
let ars = ARSCode::new(5, 3, 15, 8, 4, 42).unwrap();
let cloned = ars.clone();
let copied = ars;
assert_eq!(ars, cloned);
assert_eq!(ars, copied);
}
#[test]
fn test_ars_germany_constant() {
let germany = ARSCode::GERMANY;
assert!(germany.is_empty());
assert_eq!(germany.level(), ARSLevel::COUNTRY);
}
#[test]
fn test_ars_boundary_values() {
let max_ars = ARSCode::new(16, 9, 99, 99, 99, 999).unwrap();
assert_eq!(max_ars.l(), 16);
assert_eq!(max_ars.rb(), 9);
assert_eq!(max_ars.k(), 99);
assert_eq!(max_ars.v1(), 99);
assert_eq!(max_ars.v2(), 99);
assert_eq!(max_ars.g(), 999);
}
#[test]
fn test_ars_parse_leading_zeros() {
let ars: ARSCode = "001000000000".try_into().unwrap();
assert_eq!(ars.l(), 0);
assert_eq!(ars.rb(), 1);
assert_eq!(ars.k(), 0);
}
#[test]
fn test_ars_parent_none_at_country() {
let country = ARSCode::new(0, 0, 0, 0, 0, 0).unwrap();
assert_eq!(country.parent(), None);
}
#[test]
fn test_ars_sequential_parent_calls() {
let mut current = ARSCode::new(5, 3, 15, 8, 4, 42).unwrap();
assert_eq!(current.level(), ARSLevel::MUNICIPALITY);
current = current.parent().unwrap();
assert_eq!(current.level(), ARSLevel::ADMIN_ASSOCIATION);
current = current.parent().unwrap();
assert_eq!(current.level(), ARSLevel::COUNTY);
current = current.parent().unwrap();
assert_eq!(current.level(), ARSLevel::DISTRICT);
current = current.parent().unwrap();
assert_eq!(current.level(), ARSLevel::STATE);
current = current.parent().unwrap();
assert_eq!(current.level(), ARSLevel::COUNTRY);
assert_eq!(current.parent(), None);
}
#[cfg(feature = "serde")]
#[test]
fn test_ars_serde_ser() {
let ars = ARSCode::new(5, 3, 15, 8, 4, 42).unwrap();
assert_eq!(
"\"053150804042\"".to_string(),
serde_json::to_string(&ars).unwrap()
);
}
#[cfg(feature = "serde")]
#[test]
fn test_ars_serde_deser() {
let ars_json: ARSCode = serde_json::from_str("\"053150804042\"").unwrap();
let ars = ARSCode::new(5, 3, 15, 8, 4, 42).unwrap();
assert_eq!(ars_json, ars);
}
}