use brk_traversable::Traversable;
use brk_types::Version;
use derive_more::{Deref, DerefMut};
use schemars::JsonSchema;
use vecdb::{ReadableCloneableVec, UnaryTransform};
use crate::internal::{
ComputedVecValue, DistributionStats, LazyPerBlock, NumericValue, RollingDistribution, Windows,
};
#[derive(Clone, Deref, DerefMut, Traversable)]
#[traversable(transparent)]
pub struct LazyRollingDistribution<T, S1T>(pub DistributionStats<Windows<LazyPerBlock<T, S1T>>>)
where
T: ComputedVecValue + PartialOrd + JsonSchema,
S1T: ComputedVecValue + JsonSchema;
impl<T, S1T> LazyRollingDistribution<T, S1T>
where
T: ComputedVecValue + JsonSchema + 'static,
S1T: NumericValue + JsonSchema,
{
pub(crate) fn from_rolling_distribution<F: UnaryTransform<S1T, T>>(
name: &str,
version: Version,
source: &RollingDistribution<S1T>,
) -> Self {
let s = &source.0;
macro_rules! map_stat {
($field:ident, $suffix:expr) => {{
let src = &s.$field;
Windows {
_24h: LazyPerBlock::from_computed::<F>(
&format!("{name}_{}_24h", $suffix),
version,
src._24h.height.read_only_boxed_clone(),
&src._24h,
),
_1w: LazyPerBlock::from_computed::<F>(
&format!("{name}_{}_1w", $suffix),
version,
src._1w.height.read_only_boxed_clone(),
&src._1w,
),
_1m: LazyPerBlock::from_computed::<F>(
&format!("{name}_{}_1m", $suffix),
version,
src._1m.height.read_only_boxed_clone(),
&src._1m,
),
_1y: LazyPerBlock::from_computed::<F>(
&format!("{name}_{}_1y", $suffix),
version,
src._1y.height.read_only_boxed_clone(),
&src._1y,
),
}
}};
}
Self(DistributionStats {
min: map_stat!(min, "min"),
max: map_stat!(max, "max"),
pct10: map_stat!(pct10, "pct10"),
pct25: map_stat!(pct25, "pct25"),
median: map_stat!(median, "median"),
pct75: map_stat!(pct75, "pct75"),
pct90: map_stat!(pct90, "pct90"),
})
}
}