1use super::*;
2use crate::robj::Attributes;
3use extendr_ffi::{dataptr, R_xlen_t, SET_VECTOR_ELT, VECTOR_ELT};
4use std::iter::FromIterator;
5
6#[derive(PartialEq, Clone)]
7pub struct List {
8 pub(crate) robj: Robj,
9}
10
11impl Default for List {
12 fn default() -> Self {
13 List::new(0)
14 }
15}
16
17impl List {
18 pub fn new(size: usize) -> Self {
28 let robj = Robj::alloc_vector(SEXPTYPE::VECSXP, size);
29 Self { robj }
30 }
31
32 pub fn from_values<V>(values: V) -> Self
42 where
43 V: IntoIterator,
44 V::IntoIter: ExactSizeIterator,
45 V::Item: Into<Robj>,
46 {
47 Self {
48 robj: make_vector(SEXPTYPE::VECSXP, values),
49 }
50 }
51
52 pub fn from_pairs<V>(pairs: V) -> Self
53 where
54 V: IntoIterator,
55 V::IntoIter: ExactSizeIterator + Clone,
56 V::Item: KeyValue,
57 {
58 let iter = pairs.into_iter();
59 let mut names = Vec::with_capacity(iter.len());
60 let mut values = Vec::with_capacity(iter.len());
61 for pair in iter {
62 names.push(pair.key());
63 values.push(pair.value());
64 }
65 let mut res = List::from_values(values);
66 res.as_robj_mut()
67 .set_names(names)
68 .unwrap()
69 .as_list()
70 .unwrap()
71 }
72
73 pub fn from_hashmap<K, V>(val: HashMap<K, V>) -> Result<Self>
92 where
93 V: IntoRobj,
94 K: Into<String>,
95 {
96 let (names, values): (Vec<_>, Vec<_>) = val
97 .into_iter()
98 .map(|(k, v)| (k.into(), v.into_robj()))
99 .unzip();
100 let mut res: Self = Self::from_values(values);
101 res.set_names(names)?;
102 Ok(res)
103 }
104
105 pub fn from_names_and_values<N, V>(names: N, values: V) -> Result<Self>
108 where
109 N: IntoIterator,
110 N::IntoIter: ExactSizeIterator,
111 N::Item: ToVectorValue + AsRef<str>,
112 V: IntoIterator,
113 V::IntoIter: ExactSizeIterator,
114 V::Item: Into<Robj>,
115 {
116 let mut list = List::from_values(values);
117 list.set_names(names)?;
118 Ok(list)
119 }
120
121 pub fn values(&self) -> ListIter {
131 ListIter::from_parts(self.robj.clone(), 0, self.robj.len())
132 }
133
134 pub fn iter(&self) -> NamedListIter {
144 self.names()
146 .map(|n| n.zip(self.values()))
147 .unwrap_or_else(|| StrIter::new(self.len()).zip(self.values()))
148 }
149
150 pub fn as_slice(&self) -> &[Robj] {
152 unsafe {
153 let data = dataptr(self.robj.get()) as *const Robj;
154 let len = self.robj.len();
155 std::slice::from_raw_parts(data, len)
156 }
157 }
158
159 pub fn elt(&self, i: usize) -> Result<Robj> {
161 if i >= self.robj.len() {
162 Err(Error::OutOfRange(self.robj.clone()))
163 } else {
164 unsafe {
165 let sexp = VECTOR_ELT(self.robj.get(), i as R_xlen_t);
166 Ok(Robj::from_sexp(sexp))
167 }
168 }
169 }
170
171 pub fn set_elt(&mut self, i: usize, value: Robj) -> Result<()> {
173 single_threaded(|| unsafe {
174 if i >= self.robj.len() {
175 Err(Error::OutOfRange(self.robj.clone()))
176 } else {
177 SET_VECTOR_ELT(self.robj.get_mut(), i as R_xlen_t, value.get());
178 Ok(())
179 }
180 })
181 }
182
183 pub fn into_hashmap(self) -> HashMap<&'static str, Robj> {
197 self.as_robj().try_into().unwrap()
198 }
199}
200
201impl<T> TryFrom<&List> for HashMap<&str, T>
202where
203 T: TryFrom<Robj, Error = error::Error>,
204{
205 type Error = Error;
206
207 fn try_from(value: &List) -> Result<Self> {
208 let value = value
209 .iter()
210 .map(|(name, value)| -> Result<(&str, T)> { value.try_into().map(|x| (name, x)) })
211 .collect::<Result<HashMap<_, _>>>()?;
212
213 Ok(value)
214 }
215}
216
217impl<T> TryFrom<&List> for HashMap<String, T>
218where
219 T: TryFrom<Robj, Error = error::Error>,
220{
221 type Error = Error;
222 fn try_from(value: &List) -> Result<Self> {
223 let value: HashMap<&str, _> = value.try_into()?;
224 Ok(value.into_iter().map(|(k, v)| (k.to_string(), v)).collect())
225 }
226}
227
228impl TryFrom<&List> for HashMap<&str, Robj> {
232 type Error = Error;
233
234 fn try_from(value: &List) -> Result<Self> {
235 Ok(value.iter().collect())
236 }
237}
238
239impl TryFrom<&List> for HashMap<String, Robj> {
240 type Error = Error;
241 fn try_from(value: &List) -> Result<Self> {
242 let value: HashMap<&str, _> = value.try_into()?;
243 Ok(value.into_iter().map(|(k, v)| (k.to_string(), v)).collect())
244 }
245}
246
247impl IntoIterator for List {
248 type IntoIter = NamedListIter;
249 type Item = (&'static str, Robj);
250
251 fn into_iter(self) -> Self::IntoIter {
261 self.iter()
262 }
263}
264
265#[derive(Clone)]
285pub struct ListIter {
286 robj: Robj,
287 i: usize,
288 len: usize,
289}
290
291impl Default for ListIter {
292 fn default() -> Self {
293 ListIter::new()
294 }
295}
296
297impl ListIter {
298 pub fn new() -> Self {
300 ListIter::from_parts(().into(), 0, 0)
301 }
302
303 pub(crate) fn from_parts(robj: Robj, i: usize, len: usize) -> Self {
304 Self { robj, i, len }
305 }
306}
307
308impl Iterator for ListIter {
309 type Item = Robj;
310
311 fn size_hint(&self) -> (usize, Option<usize>) {
312 (self.len, Some(self.len))
313 }
314
315 fn next(&mut self) -> Option<Self::Item> {
316 let i = self.i;
317 self.i += 1;
318 if i >= self.len {
319 None
320 } else {
321 Some(unsafe { Robj::from_sexp(VECTOR_ELT(self.robj.get(), i as isize)) })
322 }
323 }
324
325 fn nth(&mut self, n: usize) -> Option<Self::Item> {
326 self.i += n;
327 self.next()
328 }
329}
330
331impl ExactSizeIterator for ListIter {
332 fn len(&self) -> usize {
334 self.len - self.i
335 }
336}
337
338pub struct FromList<T>(pub T);
348
349impl<T> TryFrom<&Robj> for FromList<Vec<T>>
350where
351 T: TryFrom<Robj>,
352 <T as TryFrom<Robj>>::Error: Into<Error>,
353{
354 type Error = Error;
355
356 fn try_from(robj: &Robj) -> Result<Self> {
357 let listiter: ListIter = robj.try_into()?;
358 let res: Result<Vec<_>> = listiter
359 .map(|robj| T::try_from(robj).map_err(|e| e.into()))
360 .collect();
361 res.map(FromList)
362 }
363}
364
365impl<T> TryFrom<Robj> for FromList<Vec<T>>
366where
367 T: TryFrom<Robj>,
368 <T as TryFrom<Robj>>::Error: Into<Error>,
369{
370 type Error = Error;
371
372 fn try_from(robj: Robj) -> Result<Self> {
373 <FromList<Vec<T>>>::try_from(&robj)
374 }
375}
376
377impl TryFrom<&Robj> for ListIter {
378 type Error = Error;
379
380 fn try_from(robj: &Robj) -> Result<Self> {
382 let list: List = robj.try_into()?;
383 Ok(list.values())
384 }
385}
386
387impl TryFrom<Robj> for ListIter {
388 type Error = Error;
389
390 fn try_from(robj: Robj) -> Result<Self> {
392 <ListIter>::try_from(&robj)
393 }
394}
395
396impl From<ListIter> for Robj {
397 fn from(iter: ListIter) -> Self {
406 iter.robj
407 }
408}
409
410pub trait KeyValue {
412 fn key(&self) -> String;
413 fn value(self) -> Robj;
414}
415
416impl<T: AsRef<str>> KeyValue for (T, Robj) {
417 fn key(&self) -> String {
418 self.0.as_ref().to_owned()
419 }
420 fn value(self) -> Robj {
421 self.1
422 }
423}
424
425impl<T: Into<Robj>> FromIterator<T> for List {
426 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
428 let iter_collect: Vec<_> = iter.into_iter().collect();
429 let len = iter_collect.len();
430
431 crate::single_threaded(|| unsafe {
432 let mut robj = Robj::alloc_vector(SEXPTYPE::VECSXP, len);
433 for (i, v) in iter_collect.into_iter().enumerate() {
434 let item: Robj = v.into();
440 SET_VECTOR_ELT(robj.get_mut(), i as isize, item.get());
441 }
442
443 List { robj }
444 })
445 }
446}
447
448impl Attributes for List {}
449
450impl Deref for List {
451 type Target = [Robj];
452
453 fn deref(&self) -> &Self::Target {
455 self.as_slice()
456 }
457}
458
459impl std::fmt::Debug for List {
460 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
461 if self.names().is_none() {
462 write!(
463 f,
464 "list!({})",
465 self.values()
466 .map(|v| format!("{:?}", v))
467 .collect::<Vec<_>>()
468 .join(", ")
469 )
470 } else {
471 write!(
472 f,
473 "list!({})",
474 self.iter()
475 .map(|(k, v)| if !k.is_empty() {
476 format!("{}={:?}", k, v)
477 } else {
478 format!("{:?}", v)
479 })
480 .collect::<Vec<_>>()
481 .join(", ")
482 )
483 }
484 }
485}