diff --git a/arm/src/rustler_util.rs b/arm/src/rustler_util.rs index b4027a05..1675c07d 100644 --- a/arm/src/rustler_util.rs +++ b/arm/src/rustler_util.rs @@ -18,6 +18,7 @@ use crate::utils::{bytes_to_words, words_to_bytes}; use bincode; use k256::ecdsa::{RecoveryId, Signature, SigningKey}; use k256::AffinePoint; +use rustler::types::atom; use rustler::types::map::map_new; use rustler::{atoms, Binary, Decoder, Encoder, NifResult}; use rustler::{Env, Error, OwnedBinary, Term}; @@ -94,6 +95,36 @@ pub trait RustlerDecoder<'a>: Sized + 'a { fn rustler_decode(term: Term<'a>) -> NifResult; } +impl RustlerEncoder for Option +where + T: RustlerEncoder, +{ + fn rustler_encode<'c>(&self, env: Env<'c>) -> Result, Error> { + match *self { + Some(ref value) => value.rustler_encode(env), + None => Ok(atom::nil().encode(env)), + } + } +} + +impl<'a, T> RustlerDecoder<'a> for Option +where + T: RustlerDecoder<'a>, +{ + fn rustler_decode(term: Term<'a>) -> NifResult { + if let Ok(term) = RustlerDecoder::rustler_decode(term) { + Ok(Some(term)) + } else { + let decoded_atom: atom::Atom = term.decode()?; + if decoded_atom == atom::nil() { + Ok(None) + } else { + Err(Error::BadArg) + } + } + } +} + impl RustlerEncoder for Vec { fn rustler_encode<'a>(&self, env: Env<'a>) -> Result, Error> { let mut erl_bin = OwnedBinary::new(self.len())