miniextendr_api/from_r/
logical.rs1use crate::ffi::{RLogical, Rboolean, SEXP, SEXPTYPE, SexpExt};
13use crate::from_r::{SexpError, SexpNaError, TryFromSexp, is_na_real};
14
15impl TryFromSexp for Rboolean {
16 type Error = SexpError;
17
18 #[inline]
19 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
20 let raw: RLogical = TryFromSexp::try_from_sexp(sexp)?;
21 match raw.to_option_bool() {
22 Some(false) => Ok(Rboolean::FALSE),
23 Some(true) => Ok(Rboolean::TRUE),
24 None => Err(SexpNaError {
25 sexp_type: SEXPTYPE::LGLSXP,
26 }
27 .into()),
28 }
29 }
30
31 #[inline]
32 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
33 let raw: RLogical = unsafe { TryFromSexp::try_from_sexp_unchecked(sexp)? };
34 match raw.to_option_bool() {
35 Some(false) => Ok(Rboolean::FALSE),
36 Some(true) => Ok(Rboolean::TRUE),
37 None => Err(SexpNaError {
38 sexp_type: SEXPTYPE::LGLSXP,
39 }
40 .into()),
41 }
42 }
43}
44
45impl TryFromSexp for Option<Rboolean> {
46 type Error = SexpError;
47
48 #[inline]
49 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
50 if sexp.type_of() == SEXPTYPE::NILSXP {
51 return Ok(None);
52 }
53 let raw: RLogical = TryFromSexp::try_from_sexp(sexp)?;
54 match raw.to_option_bool() {
55 Some(false) => Ok(Some(Rboolean::FALSE)),
56 Some(true) => Ok(Some(Rboolean::TRUE)),
57 None => Ok(None),
58 }
59 }
60
61 #[inline]
62 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
63 if sexp.type_of() == SEXPTYPE::NILSXP {
64 return Ok(None);
65 }
66 let raw: RLogical = unsafe { TryFromSexp::try_from_sexp_unchecked(sexp)? };
67 match raw.to_option_bool() {
68 Some(false) => Ok(Some(Rboolean::FALSE)),
69 Some(true) => Ok(Some(Rboolean::TRUE)),
70 None => Ok(None),
71 }
72 }
73}
74
75impl TryFromSexp for bool {
76 type Error = SexpError;
77
78 #[inline]
79 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
80 let raw: RLogical = TryFromSexp::try_from_sexp(sexp)?;
81 raw.to_option_bool().ok_or_else(|| {
82 SexpNaError {
83 sexp_type: SEXPTYPE::LGLSXP,
84 }
85 .into()
86 })
87 }
88
89 #[inline]
90 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
91 let raw: RLogical = unsafe { TryFromSexp::try_from_sexp_unchecked(sexp)? };
92 raw.to_option_bool().ok_or_else(|| {
93 SexpNaError {
94 sexp_type: SEXPTYPE::LGLSXP,
95 }
96 .into()
97 })
98 }
99}
100
101impl TryFromSexp for Option<bool> {
102 type Error = SexpError;
103
104 #[inline]
105 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
106 if sexp.type_of() == SEXPTYPE::NILSXP {
108 return Ok(None);
109 }
110 let raw: RLogical = TryFromSexp::try_from_sexp(sexp)?;
111 Ok(raw.to_option_bool())
112 }
113
114 #[inline]
115 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
116 if sexp.type_of() == SEXPTYPE::NILSXP {
118 return Ok(None);
119 }
120 let raw: RLogical = unsafe { TryFromSexp::try_from_sexp_unchecked(sexp)? };
121 Ok(raw.to_option_bool())
122 }
123}
124
125impl TryFromSexp for Option<RLogical> {
126 type Error = SexpError;
127
128 #[inline]
129 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
130 if sexp.type_of() == SEXPTYPE::NILSXP {
131 return Ok(None);
132 }
133 let raw: RLogical = TryFromSexp::try_from_sexp(sexp)?;
134 if raw.is_na() { Ok(None) } else { Ok(Some(raw)) }
135 }
136
137 #[inline]
138 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
139 if sexp.type_of() == SEXPTYPE::NILSXP {
140 return Ok(None);
141 }
142 let raw: RLogical = unsafe { TryFromSexp::try_from_sexp_unchecked(sexp)? };
143 if raw.is_na() { Ok(None) } else { Ok(Some(raw)) }
144 }
145}
146
147impl TryFromSexp for Option<i32> {
148 type Error = SexpError;
149
150 #[inline]
151 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
152 if sexp.type_of() == SEXPTYPE::NILSXP {
154 return Ok(None);
155 }
156 let value: i32 = TryFromSexp::try_from_sexp(sexp)?;
157 if value == crate::altrep_traits::NA_INTEGER {
158 Ok(None)
159 } else {
160 Ok(Some(value))
161 }
162 }
163
164 #[inline]
165 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
166 if sexp.type_of() == SEXPTYPE::NILSXP {
168 return Ok(None);
169 }
170 let value: i32 = unsafe { TryFromSexp::try_from_sexp_unchecked(sexp)? };
171 if value == crate::altrep_traits::NA_INTEGER {
172 Ok(None)
173 } else {
174 Ok(Some(value))
175 }
176 }
177}
178
179impl TryFromSexp for Option<f64> {
180 type Error = SexpError;
181
182 #[inline]
183 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
184 if sexp.type_of() == SEXPTYPE::NILSXP {
186 return Ok(None);
187 }
188 let value: f64 = TryFromSexp::try_from_sexp(sexp)?;
189 if is_na_real(value) {
190 Ok(None)
191 } else {
192 Ok(Some(value))
193 }
194 }
195
196 #[inline]
197 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
198 if sexp.type_of() == SEXPTYPE::NILSXP {
200 return Ok(None);
201 }
202 let value: f64 = unsafe { TryFromSexp::try_from_sexp_unchecked(sexp)? };
203 if is_na_real(value) {
204 Ok(None)
205 } else {
206 Ok(Some(value))
207 }
208 }
209}
210
211impl TryFromSexp for Option<u8> {
212 type Error = SexpError;
213
214 #[inline]
215 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
216 if sexp.type_of() == SEXPTYPE::NILSXP {
217 return Ok(None);
218 }
219 let value: u8 = TryFromSexp::try_from_sexp(sexp)?;
220 Ok(Some(value))
221 }
222
223 #[inline]
224 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
225 if sexp.type_of() == SEXPTYPE::NILSXP {
226 return Ok(None);
227 }
228 let value: u8 = unsafe { TryFromSexp::try_from_sexp_unchecked(sexp)? };
229 Ok(Some(value))
230 }
231}
232
233impl TryFromSexp for Option<crate::ffi::Rcomplex> {
234 type Error = SexpError;
235
236 #[inline]
237 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
238 use crate::altrep_traits::NA_REAL;
239
240 if sexp.type_of() == SEXPTYPE::NILSXP {
241 return Ok(None);
242 }
243 let value: crate::ffi::Rcomplex = TryFromSexp::try_from_sexp(sexp)?;
244 let na_bits = NA_REAL.to_bits();
245 if value.r.to_bits() == na_bits || value.i.to_bits() == na_bits {
246 Ok(None)
247 } else {
248 Ok(Some(value))
249 }
250 }
251
252 #[inline]
253 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
254 use crate::altrep_traits::NA_REAL;
255
256 if sexp.type_of() == SEXPTYPE::NILSXP {
257 return Ok(None);
258 }
259 let value: crate::ffi::Rcomplex = unsafe { TryFromSexp::try_from_sexp_unchecked(sexp)? };
260 let na_bits = NA_REAL.to_bits();
261 if value.r.to_bits() == na_bits || value.i.to_bits() == na_bits {
262 Ok(None)
263 } else {
264 Ok(Some(value))
265 }
266 }
267}
268