Skip to main content

deep_causality_num/float_option/
mod.rs

1/*
2 * SPDX-License-Identifier: MIT
3 * Copyright (c) 2023 - 2026. The DeepCausality Authors and Contributors. All Rights Reserved.
4 */
5
6use crate::Float;
7use core::fmt::Debug;
8
9/// A trait to abstract over float types (`f32`, `f64`) and their `Option` variants.
10///
11/// It provides a unified way to convert these types into an `Option<F>`
12/// where `F` is a type that implements the `Float` trait.
13pub trait FloatOption<F: Float>: Clone + Debug + Send + Sync + 'static {
14    /// Converts the implementing type into an `Option<F>`.
15    ///
16    /// - For a float type `F`, `NaN` is treated as a missing value (`None`).
17    /// - For `Option<F>`, this handles `Some(NaN)` by returning `None`, and passes through `Some(value)` and `None`.
18    fn to_option(&self) -> Option<F>;
19}
20
21// Implementation for any `F` that implements `Float`.
22// This covers `f32` and `f64`.
23impl<F> FloatOption<F> for F
24where
25    F: Float + Debug + Send + Sync + 'static,
26{
27    fn to_option(&self) -> Option<F> {
28        if self.is_nan() { None } else { Some(*self) }
29    }
30}
31
32// Implementation for `Option<F>`.
33// This covers `Option<f32>` and `Option<f64>`.
34impl<F> FloatOption<F> for Option<F>
35where
36    F: Float + Debug + Send + Sync + 'static,
37{
38    fn to_option(&self) -> Option<F> {
39        self.and_then(|value| if value.is_nan() { None } else { Some(value) })
40    }
41}