use std::{sync::Arc, time::Duration};
use directories::ProjectDirs;
use crate::{
error::{RLanLibError, Result},
oui::{db::OuiDb, offline_db::OfflineOuiDb, traits::Oui},
};
pub mod db;
pub mod offline_db;
pub mod traits;
pub mod types;
pub fn default(project_name: &str, max_age: Duration) -> Result<Arc<dyn Oui>> {
log::info!("initializing oui data dir");
let project_dirs =
ProjectDirs::from("", "", project_name).ok_or(RLanLibError::Oui(
format!("failed to find \"{project_name}\" oui data directory"),
))?;
let data_dir = project_dirs.data_dir();
std::fs::create_dir_all(data_dir).map_err(|e| {
RLanLibError::Oui(format!(
"failed to initialize oui data directory: {} : {}",
data_dir.display(),
e
))
})?;
let mut oui = OuiDb::new(data_dir);
let oui_age = oui.age();
if let Some(age) = oui_age
&& let Ok(elapsed) = age.elapsed()
&& elapsed > max_age
{
log::info!("oui data files are out of date: updating...");
match oui.update() {
Ok(_) => log::info!("successfully downloaded vendor data"),
Err(err) => {
log::warn!("failed to download vendor data: {}", err);
log::warn!(
"continuing with use of previously downloaded data: vendor data may be slightly out-of-date"
);
}
}
} else if oui_age.is_none() {
log::info!("downloading oui data files to {}", data_dir.display());
match oui.update() {
Ok(_) => log::info!("successfully downloaded vendor data"),
Err(err) => {
log::warn!("failed to download vendor data: {}", err);
log::warn!(
"loading offline data: vendor data may be out-of-date"
);
return Ok(Arc::new(OfflineOuiDb));
}
}
}
log::info!("loading oui data...");
oui.load_data()?;
Ok(Arc::new(oui))
}