fts_core/models/
bound.rs

1use serde::{Deserialize, Serialize};
2use utoipa::ToSchema;
3
4/// A newtype wrapper around an optional float, with convenience methods to specify an infinite-fallback.
5///
6/// Bounds are used to represent constraint values that can either be finite numbers or
7/// positive/negative infinity. When serialized, infinite values are represented as null
8/// for cleaner API responses and requests.
9#[derive(Clone, Debug, Default, Serialize, Deserialize, ToSchema)]
10#[serde(transparent)]
11pub struct Bound(Option<f64>);
12
13impl Bound {
14    /// Returns the contained value or positive infinity if None
15    ///
16    /// This is typically used for upper bounds where no limit means infinity.
17    pub fn or_pos_inf(&self) -> f64 {
18        match self.0 {
19            Some(x) => x,
20            None => f64::INFINITY,
21        }
22    }
23
24    /// Returns the contained value or negative infinity if None
25    ///
26    /// This is typically used for lower bounds where no limit means negative infinity.
27    pub fn or_neg_inf(&self) -> f64 {
28        match self.0 {
29            Some(x) => x,
30            None => f64::NEG_INFINITY,
31        }
32    }
33}
34
35impl From<f64> for Bound {
36    /// Converts a float to a Bound, mapping infinite values to None
37    fn from(value: f64) -> Self {
38        if value.is_infinite() {
39            Self(None)
40        } else {
41            Self(Some(value))
42        }
43    }
44}