use crate::{
AddressError, AddressErrorKind, Decode, IntoBin, IntoCsv, Io, Nom, Parse, PartialAddress,
from_bin, from_csv, to_bin, to_csv,
};
use derive_more::{Deref, DerefMut};
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)]
pub struct BusinessRaw {
company_name: String,
contact_name: Option<String>,
dba: Option<String>,
street_address_label: String,
license: String,
industry_code: i32,
industry_name: String,
sector_code: i32,
sector_name: String,
subsector_code: i32,
subsector_name: Option<String>,
tourism: Option<String>,
district: Option<String>,
}
#[derive(
Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize, Deref, DerefMut,
)]
pub struct BusinessesRaw(Vec<BusinessRaw>);
impl BusinessesRaw {
pub fn from_csv<P: AsRef<std::path::Path>>(path: P) -> Result<Self, Io> {
let records = from_csv(path)?;
Ok(Self(records))
}
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)]
pub struct Business {
company_name: String,
contact_name: Option<String>,
dba: Option<String>,
address: PartialAddress,
license: String,
industry_code: i32,
industry_name: String,
sector_code: i32,
sector_name: String,
subsector_code: i32,
subsector_name: Option<String>,
tourism: Option<String>,
district: Option<String>,
}
impl Business {
pub fn company_name(&self) -> String {
self.company_name.to_owned()
}
pub fn contact_name(&self) -> Option<String> {
self.contact_name.clone()
}
pub fn dba(&self) -> Option<String> {
self.dba.clone()
}
pub fn address(&self) -> PartialAddress {
self.address.clone()
}
pub fn license(&self) -> String {
self.license.to_owned()
}
pub fn industry_code(&self) -> i32 {
self.industry_code
}
pub fn industry_name(&self) -> String {
self.industry_name.to_owned()
}
pub fn sector_code(&self) -> i32 {
self.sector_code
}
pub fn sector_name(&self) -> String {
self.sector_name.to_owned()
}
pub fn subsector_code(&self) -> i32 {
self.subsector_code
}
pub fn subsector_name(&self) -> Option<String> {
self.subsector_name.clone()
}
pub fn tourism(&self) -> Option<String> {
self.tourism.clone()
}
pub fn district(&self) -> Option<String> {
self.district.clone()
}
}
impl TryFrom<BusinessRaw> for Business {
type Error = Nom;
fn try_from(raw: BusinessRaw) -> Result<Self, Self::Error> {
match Parse::address(&raw.street_address_label) {
Ok((_, address)) => Ok(Business {
company_name: raw.company_name,
contact_name: raw.contact_name,
dba: raw.dba,
address,
license: raw.license,
industry_code: raw.industry_code,
industry_name: raw.industry_name,
sector_code: raw.sector_code,
sector_name: raw.sector_name,
subsector_code: raw.subsector_code,
subsector_name: raw.subsector_name,
tourism: raw.tourism,
district: raw.district,
}),
Err(source) => Err(Nom::new(
raw.street_address_label.clone(),
source,
line!(),
file!().into(),
)),
}
}
}
#[derive(
Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize, Deref, DerefMut,
)]
pub struct Businesses(Vec<Business>);
impl Businesses {
pub fn from_raw_csv<P: AsRef<std::path::Path>>(path: P) -> Result<Self, AddressErrorKind> {
let raw = BusinessesRaw::from_csv(path)?;
let mut records = Vec::new();
for record in raw.iter() {
records.push(Business::try_from(record.clone())?);
}
Ok(Businesses(records))
}
}
impl IntoBin<Businesses> for Businesses {
fn load<P: AsRef<std::path::Path>>(path: P) -> Result<Self, AddressError> {
let config = bincode::config::standard();
match from_bin(path) {
Ok(records) => {
let (results, _) = bincode::serde::decode_from_slice::<
Self,
bincode::config::Configuration,
>(&records, config)
.map_err(|source| Decode::new(source, line!(), file!().into()))?;
Ok(results)
}
Err(source) => Err(AddressErrorKind::from(source).into()),
}
}
fn save<P: AsRef<std::path::Path>>(&self, path: P) -> Result<(), AddressError> {
to_bin(self, path)
}
}
impl IntoCsv<Businesses> for Businesses {
fn from_csv<P: AsRef<std::path::Path>>(path: P) -> Result<Self, Io> {
let records = from_csv(path)?;
Ok(Self(records))
}
fn to_csv<P: AsRef<std::path::Path>>(&mut self, path: P) -> Result<(), AddressErrorKind> {
to_csv(&mut self.0, path.as_ref().into())
}
}