ramp_maker/util/
traits.rs

1//! Numeric traits to fill some gaps in the ecosystem
2//!
3//! Much code in this library is generic over the numeric type it uses, however,
4//! there currently seem to be some holes in the ecosystem. [num-traits]
5//! basically covers anything we could need, but some of isn't available in a
6//! `no_std` context, or can't be implemented by the types from [fixed] for some
7//! reason.
8//!
9//! This module defines some custom traits and provides implementations for
10//! `f32`, `f64`, and all types from [fixed].
11//!
12//! [num-traits]: https://crates.io/crates/num-traits
13//! [fixed]: https://crates.io/crates/fixed
14
15/// Defines an interface to the square root operation
16pub trait Sqrt {
17    /// Return the square root of `self`
18    fn sqrt(self) -> Self;
19}
20
21/// Defines an interface to the `ceil` operator for rounding up
22pub trait Ceil {
23    /// Round up to the next largest integer
24    fn ceil(self) -> Self;
25}
26
27#[cfg(any(test, feature = "std"))]
28mod impl_using_std {
29    impl super::Sqrt for f32 {
30        fn sqrt(self) -> Self {
31            f32::sqrt(self)
32        }
33    }
34
35    impl super::Ceil for f32 {
36        fn ceil(self) -> Self {
37            f32::ceil(self)
38        }
39    }
40
41    impl super::Sqrt for f64 {
42        fn sqrt(self) -> Self {
43            f64::sqrt(self)
44        }
45    }
46
47    impl super::Ceil for f64 {
48        fn ceil(self) -> Self {
49            f64::ceil(self)
50        }
51    }
52}
53
54#[cfg(all(not(test), not(feature = "std"), feature = "libm"))]
55mod impl_using_libm {
56    impl super::Sqrt for f32 {
57        fn sqrt(self) -> Self {
58            libm::sqrtf(self)
59        }
60    }
61
62    impl super::Ceil for f32 {
63        fn ceil(self) -> Self {
64            libm::ceilf(self)
65        }
66    }
67
68    impl super::Sqrt for f64 {
69        fn sqrt(self) -> Self {
70            libm::sqrt(self)
71        }
72    }
73
74    impl super::Ceil for f64 {
75        fn ceil(self) -> Self {
76            libm::ceil(self)
77        }
78    }
79}
80
81mod impl_fixed {
82    use fixed::types::extra::{LeEqU128, LeEqU16, LeEqU32, LeEqU64, LeEqU8};
83    use fixed_sqrt::{
84        traits::{IsEven, LtU128, LtU16, LtU32, LtU64, LtU8},
85        FixedSqrt,
86    };
87
88    macro_rules! impl_fixed {
89        ($
90            (
91                $num:ident:
92                    Sqrt => ($($sqrt_bound:ident),*)
93                    Ceil => ($($ceil_bound:ident),*)
94            )*
95        ) => {
96            $(
97                // Can't use a blanket impl over `FixedSqrt`, as that would
98                // conflict with any other impl that anyone might want to
99                // provide.
100                impl<U> super::Sqrt for fixed::$num<U>
101                where
102                    $(U: $sqrt_bound,)*
103                {
104                    fn sqrt(self) -> Self {
105                        <Self as FixedSqrt>::sqrt(self)
106                    }
107                }
108
109                impl<U> super::Ceil for fixed::$num<U>
110                where
111                    $(U: $ceil_bound,)*
112                {
113                    fn ceil(self) -> Self {
114                        fixed::$num::ceil(self)
115                    }
116                }
117            )*
118        };
119    }
120
121    impl_fixed!(
122        FixedU8:
123            Sqrt => (LeEqU8)
124            Ceil => (LeEqU8)
125        FixedU16:
126            Sqrt => (LeEqU16)
127            Ceil => (LeEqU16)
128        FixedU32:
129            Sqrt => (LeEqU32)
130            Ceil => (LeEqU32)
131        FixedU64:
132            Sqrt => (LeEqU64)
133            Ceil => (LeEqU64)
134        FixedU128:
135            Sqrt => (LeEqU128, IsEven)
136            Ceil => (LeEqU128)
137        FixedI8:
138            Sqrt => (LtU8)
139            Ceil => (LeEqU8)
140        FixedI16:
141            Sqrt => (LtU16)
142            Ceil => (LeEqU16)
143        FixedI32:
144            Sqrt => (LtU32)
145            Ceil => (LeEqU32)
146        FixedI64:
147            Sqrt => (LtU64)
148            Ceil => (LeEqU64)
149        FixedI128:
150            Sqrt => (LtU128)
151            Ceil => (LeEqU128)
152    );
153}