#![deny(missing_docs)]
#![warn(rust_2018_idioms)]
pub mod data;
pub mod error;
pub mod ffi;
pub mod normalizer;
pub mod parser;
pub mod profiling;
pub mod types;
pub use error::{Error, Result};
pub use normalizer::{AddressNormalizer, NormalizedAddress};
pub use parser::{AddressParser, ParsedAddress};
pub use types::*;
#[derive(Debug)]
pub struct LibPostal {
config: LibPostalConfig,
}
impl LibPostal {
pub async fn new() -> Result<Self> {
Self::with_config(LibPostalConfig::default()).await
}
pub async fn with_config(config: LibPostalConfig) -> Result<Self> {
if config.auto_download_data {
let data_manager = data::DataManager::with_config(config.data_config.clone());
#[cfg(feature = "runtime-data")]
{
data_manager.ensure_data().await?;
}
#[cfg(not(feature = "runtime-data"))]
{
if !data_manager.is_data_available() {
return Err(Error::initialization_failed(
"Data files not available and runtime-data feature disabled",
));
}
}
}
ffi::initialize()?;
Ok(Self { config })
}
pub fn parser(&self) -> AddressParser {
AddressParser::new()
}
pub fn normalizer(&self) -> AddressNormalizer {
AddressNormalizer::new()
}
pub fn parse_address(&self, address: &str) -> Result<parser::ParsedAddress> {
self.parser().parse(address)
}
pub fn parse_address_with_hints(
&self,
address: &str,
language: Option<&str>,
country: Option<&str>,
) -> Result<parser::ParsedAddress> {
let mut parser = self.parser();
if let Some(lang) = language {
parser = parser.with_language(types::Language::from_str(lang));
}
if let Some(ctry) = country {
parser = parser.with_country(types::Country::from_str(ctry));
}
parser.parse(address)
}
pub fn normalize_address(&self, address: &str) -> Result<normalizer::NormalizedAddress> {
self.normalizer().normalize(address)
}
pub fn config(&self) -> &LibPostalConfig {
&self.config
}
}
#[derive(Debug, Clone)]
pub struct LibPostalConfig {
pub auto_download_data: bool,
pub verify_data_integrity: bool,
pub data_config: data::DataConfig,
}
impl Default for LibPostalConfig {
fn default() -> Self {
Self {
auto_download_data: true,
verify_data_integrity: true,
data_config: data::DataConfig::default(),
}
}
}
impl LibPostalConfig {
pub fn builder() -> LibPostalConfigBuilder {
LibPostalConfigBuilder::new()
}
}
#[derive(Debug, Clone)]
pub struct LibPostalConfigBuilder {
auto_download_data: bool,
verify_data_integrity: bool,
data_config: data::DataConfig,
}
impl LibPostalConfigBuilder {
pub fn new() -> Self {
Self {
auto_download_data: true,
verify_data_integrity: true,
data_config: data::DataConfig::default(),
}
}
pub fn auto_download_data(mut self, enabled: bool) -> Self {
self.auto_download_data = enabled;
self
}
pub fn verify_data_integrity(mut self, enabled: bool) -> Self {
self.verify_data_integrity = enabled;
self
}
pub fn data_config(mut self, config: data::DataConfig) -> Self {
self.data_config = config;
self
}
pub fn data_dir<P: Into<std::path::PathBuf>>(mut self, dir: P) -> Self {
self.data_config.data_dir = dir.into();
self
}
pub fn build(self) -> LibPostalConfig {
LibPostalConfig {
auto_download_data: self.auto_download_data,
verify_data_integrity: self.verify_data_integrity,
data_config: self.data_config,
}
}
}
impl Default for LibPostalConfigBuilder {
fn default() -> Self {
Self::new()
}
}