1use crate::coerce::TryCoerce;
27use crate::from_r::{
28 SexpError, SexpNaError, SexpTypeError, TryFromSexp, charsxp_to_str, coerce_value,
29 from_numeric_vec_with, map_strsxp_with, r_slice,
30};
31use crate::{IsNA, RLogical, Rboolean, SEXP, SEXPTYPE, SexpExt};
32
33macro_rules! impl_vec_option_try_from_sexp {
35 ($t:ty, $sexptype:ident, $dataptr:ident) => {
36 impl TryFromSexp for Vec<Option<$t>> {
37 type Error = SexpError;
38
39 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
40 let actual = sexp.type_of();
41 if actual != SEXPTYPE::$sexptype {
42 return Err(SexpTypeError {
43 expected: SEXPTYPE::$sexptype,
44 actual,
45 }
46 .into());
47 }
48
49 let len = sexp.len();
50 let ptr = unsafe { crate::sys::$dataptr(sexp) };
51 let slice = unsafe { r_slice(ptr, len) };
52
53 Ok(slice
54 .iter()
55 .map(|&v| if v.is_na() { None } else { Some(v) })
56 .collect())
57 }
58 }
59 };
60}
61
62impl TryFromSexp for Vec<Option<f64>> {
type Error = SexpError;
fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
let actual = sexp.type_of();
if actual != SEXPTYPE::REALSXP {
return Err(SexpTypeError {
expected: SEXPTYPE::REALSXP,
actual,
}.into());
}
let len = sexp.len();
let ptr = unsafe { crate::sys::REAL(sexp) };
let slice = unsafe { r_slice(ptr, len) };
Ok(slice.iter().map(|&v|
if v.is_na() { None } else { Some(v) }).collect())
}
}impl_vec_option_try_from_sexp!(f64, REALSXP, REAL);
63impl TryFromSexp for Vec<Option<i32>> {
type Error = SexpError;
fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
let actual = sexp.type_of();
if actual != SEXPTYPE::INTSXP {
return Err(SexpTypeError {
expected: SEXPTYPE::INTSXP,
actual,
}.into());
}
let len = sexp.len();
let ptr = unsafe { crate::sys::INTEGER(sexp) };
let slice = unsafe { r_slice(ptr, len) };
Ok(slice.iter().map(|&v|
if v.is_na() { None } else { Some(v) }).collect())
}
}impl_vec_option_try_from_sexp!(i32, INTSXP, INTEGER);
64
65impl TryFromSexp for Vec<Option<bool>> {
67 type Error = SexpError;
68
69 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
70 let actual = sexp.type_of();
71 if actual != SEXPTYPE::LGLSXP {
72 return Err(SexpTypeError {
73 expected: SEXPTYPE::LGLSXP,
74 actual,
75 }
76 .into());
77 }
78
79 let slice: &[RLogical] = unsafe { sexp.as_slice() };
80
81 Ok(slice.iter().map(|v| v.to_option_bool()).collect())
82 }
83
84 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
85 let actual = sexp.type_of();
86 if actual != SEXPTYPE::LGLSXP {
87 return Err(SexpTypeError {
88 expected: SEXPTYPE::LGLSXP,
89 actual,
90 }
91 .into());
92 }
93
94 let slice: &[RLogical] = unsafe { sexp.as_slice_unchecked() };
95
96 Ok(slice.iter().map(|v| v.to_option_bool()).collect())
97 }
98}
99
100impl TryFromSexp for Vec<Rboolean> {
102 type Error = SexpError;
103
104 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
105 let actual = sexp.type_of();
106 if actual != SEXPTYPE::LGLSXP {
107 return Err(SexpTypeError {
108 expected: SEXPTYPE::LGLSXP,
109 actual,
110 }
111 .into());
112 }
113
114 let slice: &[RLogical] = unsafe { sexp.as_slice() };
115
116 slice
117 .iter()
118 .map(|v| match v.to_option_bool() {
119 Some(false) => Ok(Rboolean::FALSE),
120 Some(true) => Ok(Rboolean::TRUE),
121 None => Err(SexpNaError {
122 sexp_type: SEXPTYPE::LGLSXP,
123 }
124 .into()),
125 })
126 .collect()
127 }
128}
129
130impl TryFromSexp for Vec<Option<Rboolean>> {
132 type Error = SexpError;
133
134 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
135 let actual = sexp.type_of();
136 if actual != SEXPTYPE::LGLSXP {
137 return Err(SexpTypeError {
138 expected: SEXPTYPE::LGLSXP,
139 actual,
140 }
141 .into());
142 }
143
144 let slice: &[RLogical] = unsafe { sexp.as_slice() };
145
146 Ok(slice
147 .iter()
148 .map(|v| match v.to_option_bool() {
149 Some(false) => Some(Rboolean::FALSE),
150 Some(true) => Some(Rboolean::TRUE),
151 None => None,
152 })
153 .collect())
154 }
155}
156
157impl TryFromSexp for Vec<crate::altrep_data::Logical> {
163 type Error = SexpError;
164
165 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
166 let actual = sexp.type_of();
167 if actual != SEXPTYPE::LGLSXP {
168 return Err(SexpTypeError {
169 expected: SEXPTYPE::LGLSXP,
170 actual,
171 }
172 .into());
173 }
174
175 let slice: &[RLogical] = unsafe { sexp.as_slice() };
176
177 Ok(slice
178 .iter()
179 .map(|&v| crate::altrep_data::Logical::from(v))
180 .collect())
181 }
182}
183
184impl TryFromSexp for Vec<Option<RLogical>> {
186 type Error = SexpError;
187
188 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
189 let actual = sexp.type_of();
190 if actual != SEXPTYPE::LGLSXP {
191 return Err(SexpTypeError {
192 expected: SEXPTYPE::LGLSXP,
193 actual,
194 }
195 .into());
196 }
197
198 let slice: &[RLogical] = unsafe { sexp.as_slice() };
199
200 Ok(slice
201 .iter()
202 .map(|v| if v.is_na() { None } else { Some(*v) })
203 .collect())
204 }
205}
206
207impl TryFromSexp for Vec<Option<String>> {
211 type Error = SexpError;
212 const CHARACTER_ONLY: bool = true;
213
214 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
215 map_strsxp_with(sexp, |charsxp, _i| {
216 if charsxp == SEXP::na_string() {
217 Ok(None)
218 } else {
219 Ok(Some(unsafe { charsxp_to_str(charsxp) }.to_owned()))
220 }
221 })
222 }
223}
224
225impl TryFromSexp for Vec<Option<u8>> {
227 type Error = SexpError;
228
229 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
230 let actual = sexp.type_of();
231 if actual != SEXPTYPE::RAWSXP {
232 return Err(SexpTypeError {
233 expected: SEXPTYPE::RAWSXP,
234 actual,
235 }
236 .into());
237 }
238
239 let slice: &[u8] = unsafe { sexp.as_slice() };
240
241 Ok(slice.iter().map(|&v| Some(v)).collect())
242 }
243}
244
245#[inline]
246fn try_from_sexp_numeric_option_vec<T>(sexp: SEXP) -> Result<Vec<Option<T>>, SexpError>
247where
248 i32: TryCoerce<T>,
249 f64: TryCoerce<T>,
250 u8: TryCoerce<T>,
251 <i32 as TryCoerce<T>>::Error: std::fmt::Display,
252 <f64 as TryCoerce<T>>::Error: std::fmt::Display,
253 <u8 as TryCoerce<T>>::Error: std::fmt::Display,
254{
255 from_numeric_vec_with(
256 sexp,
257 |v: i32| {
258 if v.is_na() {
259 Ok(None)
260 } else {
261 coerce_value(v).map(Some)
262 }
263 },
264 |v: f64| {
265 if v.is_na() {
266 Ok(None)
267 } else {
268 coerce_value(v).map(Some)
269 }
270 },
271 |v: u8| coerce_value(v).map(Some),
273 |v: RLogical| {
274 if v.is_na() {
275 Ok(None)
276 } else {
277 coerce_value(v.to_i32()).map(Some)
278 }
279 },
280 )
281}
282
283macro_rules! impl_vec_option_try_from_sexp_numeric {
284 ($t:ty) => {
285 impl TryFromSexp for Vec<Option<$t>> {
286 type Error = SexpError;
287
288 fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
289 try_from_sexp_numeric_option_vec(sexp)
290 }
291
292 unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error> {
293 try_from_sexp_numeric_option_vec(sexp)
294 }
295 }
296 };
297}
298
299impl TryFromSexp for Vec<Option<i8>> {
type Error = SexpError;
fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
try_from_sexp_numeric_option_vec(sexp)
}
unsafe fn try_from_sexp_unchecked(sexp: SEXP)
-> Result<Self, Self::Error> {
try_from_sexp_numeric_option_vec(sexp)
}
}impl_vec_option_try_from_sexp_numeric!(i8);
300impl TryFromSexp for Vec<Option<i16>> {
type Error = SexpError;
fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
try_from_sexp_numeric_option_vec(sexp)
}
unsafe fn try_from_sexp_unchecked(sexp: SEXP)
-> Result<Self, Self::Error> {
try_from_sexp_numeric_option_vec(sexp)
}
}impl_vec_option_try_from_sexp_numeric!(i16);
301impl TryFromSexp for Vec<Option<u16>> {
type Error = SexpError;
fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
try_from_sexp_numeric_option_vec(sexp)
}
unsafe fn try_from_sexp_unchecked(sexp: SEXP)
-> Result<Self, Self::Error> {
try_from_sexp_numeric_option_vec(sexp)
}
}impl_vec_option_try_from_sexp_numeric!(u16);
302impl TryFromSexp for Vec<Option<u32>> {
type Error = SexpError;
fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
try_from_sexp_numeric_option_vec(sexp)
}
unsafe fn try_from_sexp_unchecked(sexp: SEXP)
-> Result<Self, Self::Error> {
try_from_sexp_numeric_option_vec(sexp)
}
}impl_vec_option_try_from_sexp_numeric!(u32);
303impl TryFromSexp for Vec<Option<i64>> {
type Error = SexpError;
fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
try_from_sexp_numeric_option_vec(sexp)
}
unsafe fn try_from_sexp_unchecked(sexp: SEXP)
-> Result<Self, Self::Error> {
try_from_sexp_numeric_option_vec(sexp)
}
}impl_vec_option_try_from_sexp_numeric!(i64);
304impl TryFromSexp for Vec<Option<u64>> {
type Error = SexpError;
fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
try_from_sexp_numeric_option_vec(sexp)
}
unsafe fn try_from_sexp_unchecked(sexp: SEXP)
-> Result<Self, Self::Error> {
try_from_sexp_numeric_option_vec(sexp)
}
}impl_vec_option_try_from_sexp_numeric!(u64);
305impl TryFromSexp for Vec<Option<isize>> {
type Error = SexpError;
fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
try_from_sexp_numeric_option_vec(sexp)
}
unsafe fn try_from_sexp_unchecked(sexp: SEXP)
-> Result<Self, Self::Error> {
try_from_sexp_numeric_option_vec(sexp)
}
}impl_vec_option_try_from_sexp_numeric!(isize);
306impl TryFromSexp for Vec<Option<usize>> {
type Error = SexpError;
fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
try_from_sexp_numeric_option_vec(sexp)
}
unsafe fn try_from_sexp_unchecked(sexp: SEXP)
-> Result<Self, Self::Error> {
try_from_sexp_numeric_option_vec(sexp)
}
}impl_vec_option_try_from_sexp_numeric!(usize);
307impl TryFromSexp for Vec<Option<f32>> {
type Error = SexpError;
fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error> {
try_from_sexp_numeric_option_vec(sexp)
}
unsafe fn try_from_sexp_unchecked(sexp: SEXP)
-> Result<Self, Self::Error> {
try_from_sexp_numeric_option_vec(sexp)
}
}impl_vec_option_try_from_sexp_numeric!(f32);
308