use crate::{CoreError, Result};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::fmt;
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
pub struct Confidence(f64);
impl Confidence {
pub const MIN: f64 = 0.0;
pub const MAX: f64 = 1.0;
pub const ZERO: Self = Self(Self::MIN);
pub const ONE: Self = Self(Self::MAX);
pub fn new(value: f64) -> Result<Self> {
if !value.is_finite() {
return Err(CoreError::invalid_confidence(
value,
"confidence must be finite",
));
}
if !(Self::MIN..=Self::MAX).contains(&value) {
return Err(CoreError::invalid_confidence(
value,
"confidence must be between 0.0 and 1.0 inclusive",
));
}
let normalized = if value == 0.0 { 0.0 } else { value };
Ok(Self(normalized))
}
pub fn is_valid_value(value: f64) -> bool {
value.is_finite() && (Self::MIN..=Self::MAX).contains(&value)
}
pub fn value(self) -> f64 {
self.0
}
pub fn is_zero(self) -> bool {
self.0.to_bits() == Self::MIN.to_bits()
}
pub fn is_certain(self) -> bool {
self.0.to_bits() == Self::MAX.to_bits()
}
}
impl Serialize for Confidence {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_f64(self.0)
}
}
impl<'de> Deserialize<'de> for Confidence {
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let value = f64::deserialize(deserializer)?;
Self::new(value).map_err(serde::de::Error::custom)
}
}
impl TryFrom<f64> for Confidence {
type Error = CoreError;
fn try_from(value: f64) -> Result<Self> {
Self::new(value)
}
}
impl fmt::Display for Confidence {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "{}", self.0)
}
}