Type Conversions
The type Value
represents Lisp values:
- They can be copied around, but cannot outlive the
Env
they come from. - They are "proxy values": only useful when converted to Rust values, or used as arguments when calling Lisp functions.
Converting a Lisp Value
to Rust
This is enabled for types that implement FromLisp
. Most built-in types are supported. Note that conversion may fail, so the return type is Result<T>
.
#![allow(unused)] fn main() { let i: i64 = value.into_rust()?; // error if Lisp value is not an integer let f: f64 = value.into_rust()?; // error if Lisp value is nil let s = value.into_rust::<String>()?; let s: Option<&str> = value.into_rust()?; // None if Lisp value is nil }
It's better to declare input types for #[defun]
than calling .into_rust()
, unless delayed conversion is needed.
Converting a Rust Value to Lisp
This is enabled for types that implement IntoLisp
. Most built-in types are supported. Note that conversion may fail, so the return type is Result<Value<'_>>
.
#![allow(unused)] fn main() { "abc".into_lisp(env)?; "a\0bc".into_lisp(env)?; // NulError (Lisp string cannot contain null byte) 5.into_lisp(env)?; 65.3.into_lisp(env)?; ().into_lisp(env)?; // nil true.into_lisp(env)?; // t false.into_lisp(env)?; // nil }
It's better to declare return type for #[defun]
than calling .into_lisp(env)
, whenever possible.
Integers
Integer conversion is lossless by default, which means that a module will signal an "out of range" rust-error
in cases such as:
- A
#[defun]
expectingu8
gets passed-1
. - A
#[defun]
returningu64
returns a value larger thani64::max_value()
.
To disable this behavior, use the lossy-integer-conversion
feature:
[dependencies.emacs]
features = ["lossy-integer-conversion"]
Support for Rust's NonZero
integer types is disabled by default. To enable it, use the nonzero-integer-conversion
feature:
[dependencies.emacs]
features = ["nonzero-integer-conversion"]
Strings
By default, no utf-8 validation is done when converting Lisp strings into Rust strings, because the string data returned by Emacs is guaranteed to be valid utf-8 sequence. If you think you've otherwise encountered an Emacs bug, utf-8 validation can be enabled through a feature:
[dependencies.emacs]
features = ["utf-8-validation"]
Vectors
Lisp vectors are represented by the type Vector
, which can be considered a "sub-type" of Value
.
To construct Lisp vectors, use env.make_vector
and env.vector
, which are efficient wrappers of Emacs's built-in subroutines make-vector
and vector
.
#![allow(unused)] fn main() { env.make_vector(5, ())?; env.vector([1, 2, 3])?; env.vector((1, "x", true))?; }