emacs/types/
integer.rs

1use super::*;
2
3impl FromLisp<'_> for i64 {
4    fn from_lisp(value: Value<'_>) -> Result<Self> {
5        unsafe_raw_call!(value.env, extract_integer, value.raw)
6    }
7}
8
9macro_rules! int_from_lisp {
10    ($name:ident) => {
11        impl FromLisp<'_> for $name {
12            #[cfg(not(feature = "lossy-integer-conversion"))]
13            fn from_lisp(value: Value<'_>) -> Result<$name> {
14                let i: i64 = value.into_rust()?;
15                Ok(i.try_into()?)
16            }
17
18            #[cfg(feature = "lossy-integer-conversion")]
19            fn from_lisp(value: Value<'_>) -> Result<$name> {
20                let i: i64 = value.into_rust()?;
21                Ok(i as $name)
22            }
23        }
24    }
25}
26
27int_from_lisp!(i8);
28int_from_lisp!(i16);
29int_from_lisp!(i32);
30int_from_lisp!(isize);
31
32int_from_lisp!(u8);
33int_from_lisp!(u16);
34int_from_lisp!(u32);
35int_from_lisp!(u64);
36int_from_lisp!(usize);
37
38// -------------------------------------------------------------------------------------------------
39
40macro_rules! nonzero_int_from_lisp {
41    ($name:ident($primitive:ident)) => {
42        impl FromLisp<'_> for std::num::$name {
43            #[cfg(not(feature = "lossy-integer-conversion"))]
44            fn from_lisp(value: Value<'_>) -> Result<std::num::$name> {
45                let i: i64 = value.into_rust()?;
46                let i: $primitive = i.try_into()?;
47                Ok(i.try_into()?)
48            }
49
50            #[cfg(feature = "lossy-integer-conversion")]
51            fn from_lisp(value: Value<'_>) -> Result<std::num::$name> {
52                let i: i64 = value.into_rust()?;
53                let i: $primitive = i as $primitive;
54                Ok(i.try_into()?)
55            }
56        }
57    }
58}
59
60nonzero_int_from_lisp!(NonZeroU8(u8));
61nonzero_int_from_lisp!(NonZeroU16(u16));
62nonzero_int_from_lisp!(NonZeroU32(u32));
63nonzero_int_from_lisp!(NonZeroU64(u64));
64nonzero_int_from_lisp!(NonZeroUsize(usize));
65
66nonzero_int_from_lisp!(NonZeroI8(i8));
67nonzero_int_from_lisp!(NonZeroI16(i16));
68nonzero_int_from_lisp!(NonZeroI32(i32));
69nonzero_int_from_lisp!(NonZeroI64(i64));
70nonzero_int_from_lisp!(NonZeroIsize(isize));
71
72// -------------------------------------------------------------------------------------------------
73
74impl IntoLisp<'_> for i64 {
75    fn into_lisp(self, env: &Env) -> Result<Value<'_>> {
76        unsafe_raw_call_value_unprotected!(env, make_integer, self)
77    }
78}
79
80macro_rules! int_into_lisp {
81    ($name:ident) => {
82        impl IntoLisp<'_> for $name {
83            #[inline]
84            fn into_lisp(self, env: &Env) -> Result<Value<'_>> {
85                (self as i64).into_lisp(env)
86            }
87        }
88    };
89    ($name:ident, lossless) => {
90        impl IntoLisp<'_> for $name {
91            fn into_lisp(self, env: &Env) -> Result<Value<'_>> {
92                let i: i64 = self.try_into()?;
93                i.into_lisp(env)
94            }
95        }
96    };
97}
98
99// Types where `as i64` is lossless.
100int_into_lisp!(i8);
101int_into_lisp!(i16);
102int_into_lisp!(i32);
103int_into_lisp!(u8);
104int_into_lisp!(u16);
105int_into_lisp!(u32);
106
107// Types where `as i64` is lossy.
108#[cfg(feature = "lossy-integer-conversion")]
109int_into_lisp!(isize);
110#[cfg(feature = "lossy-integer-conversion")]
111int_into_lisp!(u64);
112#[cfg(feature = "lossy-integer-conversion")]
113int_into_lisp!(usize);
114#[cfg(not(feature = "lossy-integer-conversion"))]
115int_into_lisp!(isize, lossless);
116#[cfg(not(feature = "lossy-integer-conversion"))]
117int_into_lisp!(u64, lossless);
118#[cfg(not(feature = "lossy-integer-conversion"))]
119int_into_lisp!(usize, lossless);
120
121// -------------------------------------------------------------------------------------------------
122
123macro_rules! nonzero_int_into_lisp {
124    ($name:ident) => {
125        #[cfg(feature = "nonzero-integer-conversion")]
126        impl IntoLisp<'_> for std::num::$name {
127            #[inline]
128            fn into_lisp(self, env: &Env) -> Result<Value<'_>> {
129                self.get().into_lisp(env)
130            }
131        }
132    };
133}
134
135nonzero_int_into_lisp!(NonZeroU8);
136nonzero_int_into_lisp!(NonZeroU16);
137nonzero_int_into_lisp!(NonZeroU32);
138nonzero_int_into_lisp!(NonZeroU64);
139nonzero_int_into_lisp!(NonZeroUsize);
140
141nonzero_int_into_lisp!(NonZeroI8);
142nonzero_int_into_lisp!(NonZeroI16);
143nonzero_int_into_lisp!(NonZeroI32);
144nonzero_int_into_lisp!(NonZeroI64);
145nonzero_int_into_lisp!(NonZeroIsize);