otter/types/terms/
float.rs1use core::marker::PhantomData;
4
5use crate::types::sealed::Sealed;
6use crate::types::{Env, Invariant, RawTerm, Term};
7
8#[derive(Clone, Copy)]
11pub struct Float<'id> {
12 raw_term: RawTerm,
13 _id: Invariant<'id>,
14}
15
16impl<'id> Float<'id> {
17 #[crate::raw]
18 pub(crate) fn from_raw(raw_term: RawTerm) -> Self {
19 Self { raw_term, _id: PhantomData }
20 }
21
22 pub fn from_f64(env: impl Env<'id>, val: f64) -> Option<Self> {
29 if !val.is_finite() {
30 return None;
31 }
32 let raw_term = unsafe { enif_ffi::make_double(env.raw_env(), val) };
33 Some(Float { raw_term, _id: PhantomData })
34 }
35
36 pub fn to_f64(self, env: impl Env<'id>) -> f64 {
39 let mut val: f64 = 0.0;
40 let ok = unsafe { enif_ffi::get_double(env.raw_env(), self.raw_term, &mut val) };
43 assert!(ok != 0, "enif_get_double failed on a validated Float");
44 val
45 }
46}
47
48impl<'id> Sealed for Float<'id> {}
49
50impl<'id> Term<'id> for Float<'id> {
51 fn raw_term(self) -> RawTerm {
52 self.raw_term
53 }
54}
55
56impl PartialEq for Float<'_> {
57 fn eq(&self, other: &Self) -> bool {
58 unsafe { enif_ffi::is_identical(self.raw_term, other.raw_term) != 0 }
59 }
60}
61
62impl Eq for Float<'_> {}
63
64impl PartialOrd for Float<'_> {
65 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
66 Some(self.cmp(other))
67 }
68}
69
70impl Ord for Float<'_> {
71 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
72 let c = unsafe { enif_ffi::compare(self.raw_term, other.raw_term) };
73 c.cmp(&0)
74 }
75}
76
77impl std::fmt::Debug for Float<'_> {
78 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
79 write!(f, "Float")
80 }
81}