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
75
76
77
78
79
80
81
82
83
84
85
use std::{cell::RefCell, ffi::CString};
use emacs_module::{emacs_runtime, emacs_env, emacs_value};
use crate::{Value, Result, IntoLisp, call::IntoLispArgs};
#[derive(Debug)]
pub struct Env {
pub(crate) raw: *mut emacs_env,
pub(crate) protected: RefCell<Vec<emacs_value>>,
}
impl Env {
#[doc(hidden)]
pub unsafe fn new(raw: *mut emacs_env) -> Self {
let protected = RefCell::new(vec![]);
Self { raw, protected }
}
#[doc(hidden)]
pub unsafe fn from_runtime(runtime: *mut emacs_runtime) -> Self {
let get_env = (*runtime).get_environment.expect("Cannot get Emacs environment");
let raw = get_env(runtime);
Self::new(raw)
}
#[doc(hidden)]
pub fn raw(&self) -> *mut emacs_env {
self.raw
}
pub fn intern(&self, name: &str) -> Result<Value<'_>> {
unsafe_raw_call_value!(self, intern, CString::new(name)?.as_ptr())
}
pub fn type_of<'e>(&'e self, value: Value<'e>) -> Result<Value<'_>> {
unsafe_raw_call_value!(self, type_of, value.raw)
}
#[deprecated(since = "0.10.0", note = "Please use `value.is_not_nil()` instead")]
pub fn is_not_nil<'e>(&'e self, value: Value<'e>) -> bool {
unsafe_raw_call_no_exit!(self, is_not_nil, value.raw)
}
#[deprecated(since = "0.10.0", note = "Please use `value1.eq(value2)` instead")]
pub fn eq<'e>(&'e self, a: Value<'e>, b: Value<'e>) -> bool {
unsafe_raw_call_no_exit!(self, eq, a.raw, b.raw)
}
pub fn cons<'e, A, B>(&'e self, car: A, cdr: B) -> Result<Value<'_>> where A: IntoLisp<'e>, B: IntoLisp<'e> {
self.call("cons", (car, cdr))
}
pub fn list<'e, A>(&'e self, args: A) -> Result<Value<'_>> where A: IntoLispArgs<'e> {
self.call("list", args)
}
pub fn provide(&self, name: &str) -> Result<Value<'_>> {
let name = self.intern(name)?;
self.call("provide", [name])
}
pub fn message<T: AsRef<str>>(&self, text: T) -> Result<Value<'_>> {
self.call("message", (text.as_ref(),))
}
}
impl Drop for Env {
fn drop(&mut self) {
#[cfg(build = "debug")]
println!("Unrooting {} values protected by {:?}", self.protected.borrow().len(), self);
for raw in self.protected.borrow().iter() {
unsafe_raw_call_no_exit!(self, free_global_ref, *raw);
}
}
}