use async_trait::async_trait;
use crate::{
error::Result,
tracker::{
DhlTracker, GlsTracker, PostNLTracker, TrunkrsTracker,
models::TrackerContext,
},
};
use std::sync::Mutex;
use super::models::Package;
type Registry = Mutex<Vec<Box<dyn Fn() -> Box<dyn Tracker> + Send + Sync>>>;
lazy_static::lazy_static! {
static ref REGISTRY: Registry = Mutex::new(vec![
Box::new(|| Box::new(PostNLTracker)),
Box::new(|| Box::new(DhlTracker)),
Box::new(|| Box::new(GlsTracker)),
Box::new(|| Box::new(TrunkrsTracker)),
]);
}
#[async_trait]
pub trait Tracker: Send + Sync {
fn can_handle(&self, url: &str) -> bool;
async fn get_raw(&self, url: &str, ctx: &TrackerContext) -> Result<String>;
fn parse(&self, text: String) -> Result<Package>;
}
pub fn register(creator: Box<dyn Fn() -> Box<dyn Tracker> + Send + Sync>) {
REGISTRY.lock().unwrap().push(creator);
}
pub fn get_handler(url: &str) -> Result<Box<dyn Tracker>> {
for creator in REGISTRY
.lock()
.map_err(|err| format!("Error unlocking mutex: {err}"))?
.iter()
{
let tracker = creator();
if tracker.can_handle(url) {
return Ok(tracker);
}
}
Err(format!("Couldn't find a handler for {}", url).into())
}