Source code for tburundigeo.domain.entities

"""Core business entities for Burundi administrative divisions."""

import re
from dataclasses import dataclass
from typing import Optional


[docs] @dataclass(frozen=True) class Province: """Represents a province in Burundi.""" code: str name: str capital: str
[docs] def __post_init__(self) -> None: """Validate province data after initialization.""" self._validate_code(self.code) self._validate_name(self.name) self._validate_capital(self.capital)
def _validate_code(self, code: str) -> None: """Validate province code format.""" if not code or not isinstance(code, str): raise ValueError("Province code must be a non-empty string") # Expected format: BI-PR-XX (where XX is a number) if not re.match(r'^BI-PR-\d{2}$', code): raise ValueError(f"Invalid province code format: {code}") def _validate_name(self, name: str) -> None: """Validate province name.""" if not name or not isinstance(name, str): raise ValueError("Province name must be a non-empty string") if len(name.strip()) < 2: raise ValueError("Province name must be at least 2 characters long") def _validate_capital(self, capital: str) -> None: """Validate province capital.""" if not capital or not isinstance(capital, str): raise ValueError("Province capital must be a non-empty string") if len(capital.strip()) < 2: raise ValueError("Province capital must be at least 2 characters long")
[docs] def __str__(self) -> str: """String representation of the province.""" return f"Province({self.code}: {self.name}, Capital: {self.capital})"
[docs] @dataclass(frozen=True) class Commune: """Represents a commune in Burundi.""" code: str name: str capital: str province_code: str
[docs] def __post_init__(self) -> None: """Validate commune data after initialization.""" self._validate_code(self.code) self._validate_name(self.name) self._validate_capital(self.capital) self._validate_province_code(self.province_code)
def _validate_code(self, code: str) -> None: """Validate commune code format.""" if not code or not isinstance(code, str): raise ValueError("Commune code must be a non-empty string") # Expected format: BI-CO-XX-YY (where XX is province, YY is commune) if not re.match(r'^BI-CO-\d{2}-\d{2}$', code): raise ValueError(f"Invalid commune code format: {code}") def _validate_name(self, name: str) -> None: """Validate commune name.""" if not name or not isinstance(name, str): raise ValueError("Commune name must be a non-empty string") if len(name.strip()) < 2: raise ValueError("Commune name must be at least 2 characters long") def _validate_capital(self, capital: str) -> None: """Validate commune capital.""" if not capital or not isinstance(capital, str): raise ValueError("Commune capital must be a non-empty string") if len(capital.strip()) < 2: raise ValueError("Commune capital must be at least 2 characters long") def _validate_province_code(self, province_code: str) -> None: """Validate province code reference.""" if not province_code or not isinstance(province_code, str): raise ValueError("Province code must be a non-empty string") # Should match province code format if not re.match(r'^BI-PR-\d{2}$', province_code): raise ValueError(f"Invalid province code format: {province_code}")
[docs] def __str__(self) -> str: """String representation of the commune.""" return f"Commune({self.code}: {self.name}, Capital: {self.capital})"
[docs] @dataclass(frozen=True) class Zone: """Represents a zone in Burundi.""" code: str name: str chief_town: str commune_code: str
[docs] def __post_init__(self) -> None: """Validate zone data after initialization.""" self._validate_code(self.code) self._validate_name(self.name) self._validate_chief_town(self.chief_town) self._validate_commune_code(self.commune_code)
def _validate_code(self, code: str) -> None: """Validate zone code format.""" if not code or not isinstance(code, str): raise ValueError("Zone code must be a non-empty string") # Expected format: BI-ZO-XX-XX-XX (where XX are numbers) if not re.match(r'^BI-ZO-\d{2}-\d{2}-\d{2}$', code): raise ValueError(f"Invalid zone code format: {code}") def _validate_name(self, name: str) -> None: """Validate zone name.""" if not name or not isinstance(name, str): raise ValueError("Zone name must be a non-empty string") if len(name.strip()) < 2: raise ValueError("Zone name must be at least 2 characters long") def _validate_chief_town(self, chief_town: str) -> None: """Validate zone chief town.""" if not chief_town or not isinstance(chief_town, str): raise ValueError("Zone chief town must be a non-empty string") if len(chief_town.strip()) < 2: raise ValueError("Zone chief town must be at least 2 characters long") def _validate_commune_code(self, commune_code: str) -> None: """Validate commune code reference.""" if not commune_code or not isinstance(commune_code, str): raise ValueError("Commune code must be a non-empty string") # Should match commune code format if not re.match(r'^BI-CO-\d{2}-\d{2}$', commune_code): raise ValueError(f"Invalid commune code format: {commune_code}")
[docs] def __str__(self) -> str: """String representation of the zone.""" return f"Zone({self.code}: {self.name}, Chief town: {self.chief_town})"
[docs] @dataclass(frozen=True) class Quartier: """Represents a quartier (neighborhood) in Burundi.""" code: str name: str zone_code: str
[docs] def __post_init__(self) -> None: """Validate quartier data after initialization.""" self._validate_code(self.code) self._validate_name(self.name) self._validate_zone_code(self.zone_code)
def _validate_code(self, code: str) -> None: """Validate quartier code format.""" if not code or not isinstance(code, str): raise ValueError("Quartier code must be a non-empty string") # Expected format: BI-QT-XX-YY-ZZ-WW if not re.match(r'^BI-QT-\d{2}-\d{2}-\d{2}-\d{2}$', code): raise ValueError(f"Invalid quartier code format: {code}") def _validate_name(self, name: str) -> None: """Validate quartier name.""" if not name or not isinstance(name, str): raise ValueError("Quartier name must be a non-empty string") if len(name.strip()) < 2: raise ValueError("Quartier name must be at least 2 characters long") def _validate_zone_code(self, zone_code: str) -> None: """Validate zone code reference.""" if not zone_code or not isinstance(zone_code, str): raise ValueError("Zone code must be a non-empty string") # Should match zone code format if not re.match(r'^BI-ZO-\d{2}-\d{2}-\d{2}$', zone_code): raise ValueError(f"Invalid zone code format: {zone_code}")
[docs] def __str__(self) -> str: """String representation of the quartier.""" return f"Quartier({self.code}: {self.name})"