use std::{net::SocketAddr, ops::Deref, time::Duration};
use serde::Deserialize;
#[derive(Debug, Deserialize)]
pub struct Config {
pub sink: Sink,
#[serde(alias = "address")]
pub listen: SocketAddr,
#[serde(default)]
pub retention: Retention,
#[serde(default = "default_quantiles")]
pub quantiles: Vec<Quantile>,
#[serde(default)]
pub global_labels: Vec<(String, String)>,
#[serde(with = "humantime_serde", default = "default_compaction_interval")]
pub compaction_interval: Duration,
}
#[derive(Debug, PartialEq, Deserialize)]
pub enum Sink {
#[serde(alias = "Prometheus")]
OpenMetrics,
}
#[derive(Debug, PartialEq, Deserialize, Default)]
pub enum Retention {
Forever,
#[default]
ResetOnScrape,
}
#[derive(Debug, Clone, Copy, Deserialize)]
#[serde(try_from = "f64")]
pub struct Quantile(f64);
impl Deref for Quantile {
type Target = f64;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl TryFrom<f64> for Quantile {
type Error = String;
fn try_from(value: f64) -> Result<Self, Self::Error> {
(0.0..=1.0)
.contains(&value)
.then_some(Self(value))
.ok_or_else(|| format!("invalid quantile {value}, must be in the range [0.0, 1.0]"))
}
}
fn default_quantiles() -> Vec<Quantile> {
[0.75, 0.9, 0.95, 0.99].into_iter().map(Quantile).collect()
}
fn default_compaction_interval() -> Duration {
Duration::from_millis(1100)
}