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