use async_trait::async_trait;
use db_core::errors::DBResult;
use serde::{Deserialize, Serialize};
use crate::data::Data;
#[async_trait]
pub trait Stats: std::marker::Send + std::marker::Sync + CloneStats {
async fn record_fetch(&self, d: &Data, key: &str) -> DBResult<()>;
async fn record_solve(&self, d: &Data, key: &str) -> DBResult<()>;
async fn record_confirm(&self, d: &Data, key: &str) -> DBResult<()>;
async fn fetch(&self, d: &Data, user: &str, key: &str) -> DBResult<CaptchaStats>;
}
pub trait CloneStats {
fn clone_stats(&self) -> Box<dyn Stats>;
}
impl<T> CloneStats for T
where
T: Stats + Clone + 'static,
{
fn clone_stats(&self) -> Box<dyn Stats> {
Box::new(self.clone())
}
}
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
pub struct CaptchaStats {
pub config_fetches: Vec<i64>,
pub solves: Vec<i64>,
pub confirms: Vec<i64>,
}
#[derive(Clone, Default, PartialEq, Debug)]
pub struct Real;
#[async_trait]
impl Stats for Real {
async fn record_fetch(&self, d: &Data, key: &str) -> DBResult<()> {
d.db.record_fetch(key).await
}
async fn record_solve(&self, d: &Data, key: &str) -> DBResult<()> {
d.db.record_solve(key).await
}
async fn record_confirm(&self, d: &Data, key: &str) -> DBResult<()> {
d.db.record_confirm(key).await
}
async fn fetch(&self, d: &Data, user: &str, key: &str) -> DBResult<CaptchaStats> {
let config_fetches_fut = d.db.fetch_config_fetched(user, key);
let solves_fut = d.db.fetch_solve(user, key);
let confirms_fut = d.db.fetch_confirm(user, key);
let (config_fetches, solves, confirms) =
futures::try_join!(config_fetches_fut, solves_fut, confirms_fut)?;
let res = CaptchaStats {
config_fetches,
solves,
confirms,
};
Ok(res)
}
}
#[derive(Clone, Default, PartialEq, Debug)]
pub struct Dummy;
#[async_trait]
impl Stats for Dummy {
async fn record_fetch(&self, _: &Data, _: &str) -> DBResult<()> {
Ok(())
}
async fn record_solve(&self, _: &Data, _: &str) -> DBResult<()> {
Ok(())
}
async fn record_confirm(&self, _: &Data, _: &str) -> DBResult<()> {
Ok(())
}
async fn fetch(&self, _: &Data, _: &str, _: &str) -> DBResult<CaptchaStats> {
Ok(CaptchaStats::default())
}
}