extendr_api/wrapper/
promise.rs1use super::*;
2
3#[derive(PartialEq, Clone)]
5pub struct Promise {
6 pub(crate) robj: Robj,
7}
8
9impl Promise {
10 #[cfg(feature = "non-api")]
21 pub fn from_parts(code: Robj, environment: Environment) -> Result<Self> {
22 single_threaded(|| unsafe {
23 let sexp = Rf_allocSExp(SEXPTYPE::PROMSXP);
24 let robj = Robj::from_sexp(sexp);
25 SET_PRCODE(sexp, code.get());
26 SET_PRENV(sexp, environment.robj.get());
27 SET_PRVALUE(sexp, R_UnboundValue);
28 Ok(Promise { robj })
29 })
30 }
31
32 #[cfg(feature = "non-api")]
33 pub fn code(&self) -> Robj {
35 unsafe {
36 let sexp = self.robj.get();
37 Robj::from_sexp(PRCODE(sexp))
38 }
39 }
40
41 #[cfg(feature = "non-api")]
42 pub fn environment(&self) -> Environment {
44 unsafe {
45 let sexp = self.robj.get();
46 Robj::from_sexp(PRENV(sexp)).try_into().unwrap()
47 }
48 }
49
50 #[cfg(feature = "non-api")]
51 pub fn value(&self) -> Robj {
53 unsafe {
54 let sexp = self.robj.get();
55 Robj::from_sexp(PRVALUE(sexp))
56 }
57 }
58
59 #[cfg(feature = "non-api")]
60 pub fn seen(&self) -> i32 {
62 unsafe {
63 let sexp = self.robj.get();
64 PRSEEN(sexp)
65 }
66 }
67
68 #[cfg(feature = "non-api")]
69 pub fn eval(&self) -> Result<Robj> {
79 assert!(self.is_promise());
80 if !self.value().is_unbound_value() {
81 Ok(self.value())
82 } else {
83 self.robj.eval()
84 }
85 }
86}
87
88impl std::fmt::Debug for Promise {
89 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
90 let mut result = f.debug_struct("Promise");
91
92 #[cfg(feature = "non-api")]
93 {
94 let result = result.field("code", &self.code());
95 let result = result.field("environment", &self.environment());
96 }
97 result.finish()
98 }
99}