1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
use super::*;
#[derive(PartialEq, Clone)]
pub struct Language {
pub(crate) robj: Robj,
}
impl Language {
pub fn from_values<T>(values: T) -> Self
where
T: IntoIterator,
T::IntoIter: DoubleEndedIterator,
T::Item: Into<Robj>,
{
single_threaded(|| unsafe {
let mut res = R_NilValue;
let mut num_protected = 0;
for val in values.into_iter().rev() {
let val = Rf_protect(val.into().get());
res = Rf_protect(Rf_lcons(val, res));
num_protected += 2;
}
let robj = Robj::from_sexp(res);
Rf_unprotect(num_protected);
Language { robj }
})
}
pub fn iter(&self) -> PairlistIter {
unsafe {
PairlistIter {
robj: self.robj.clone(),
list_elem: self.robj.get(),
}
}
}
pub fn names(&self) -> impl Iterator<Item = &'static str> {
self.iter().map(|(tag, _)| tag)
}
pub fn values(&self) -> impl Iterator<Item = Robj> {
self.iter().map(|(_, robj)| robj)
}
}
impl std::fmt::Debug for Language {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"lang!({})",
self.iter()
.map(|(k, v)| if k.is_empty() {
format!("{:?}", v)
} else {
format!("{}={:?}", k, v)
})
.collect::<Vec<_>>()
.join(", ")
)?;
Ok(())
}
}