diff --git a/arm/src/rustler_util.rs b/arm/src/rustler_util.rs index b4027a05..a40d82b0 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()) @@ -1027,10 +1058,8 @@ impl<'a> RustlerDecoder<'a> for Transaction { let delta_proof: Delta = delta_proof_term.decode()?; let expected_balance_term = term.map_get(at_expected_balance().encode(term.get_env()))?; - let expected_balance: Option> = match expected_balance_term.decode::<()>() { - Ok(_) => None, - Err(_) => Some(RustlerDecoder::rustler_decode(expected_balance_term)?), - }; + let expected_balance: Option> = + RustlerDecoder::rustler_decode(expected_balance_term)?; Ok(Transaction { actions,