use crate::codec::{CodecError, Decoder, Encoder};
use crate::types::{AnyTerm, Env, Integer};
macro_rules! narrow_signed {
($($t:ty),+ $(,)?) => { $(
impl<'id> Encoder<'id> for $t {
fn encode(&self, env: impl Env<'id>) -> Result<AnyTerm<'id>, CodecError> {
Integer::from_i64(env, i64::from(*self)).encode(env)
}
}
impl<'id> Decoder<'id> for $t {
fn decode(term: AnyTerm<'id>, env: impl Env<'id>) -> Result<Self, CodecError> {
let val = Integer::decode(term, env)?.to_i64(env).ok_or(CodecError::IntegerOverflow)?;
Self::try_from(val).map_err(|_| CodecError::IntegerOverflow)
}
}
)+ };
}
macro_rules! narrow_unsigned {
($($t:ty),+ $(,)?) => { $(
impl<'id> Encoder<'id> for $t {
fn encode(&self, env: impl Env<'id>) -> Result<AnyTerm<'id>, CodecError> {
Integer::from_u64(env, u64::from(*self)).encode(env)
}
}
impl<'id> Decoder<'id> for $t {
fn decode(term: AnyTerm<'id>, env: impl Env<'id>) -> Result<Self, CodecError> {
let val = Integer::decode(term, env)?.to_u64(env).ok_or(CodecError::IntegerOverflow)?;
Self::try_from(val).map_err(|_| CodecError::IntegerOverflow)
}
}
)+ };
}
narrow_signed!(i8, i16, i32);
narrow_unsigned!(u8, u16, u32);
impl<'id> Encoder<'id> for i64 {
fn encode(&self, env: impl Env<'id>) -> Result<AnyTerm<'id>, CodecError> {
Integer::from_i64(env, *self).encode(env)
}
}
impl<'id> Decoder<'id> for i64 {
fn decode(term: AnyTerm<'id>, env: impl Env<'id>) -> Result<Self, CodecError> {
Integer::decode(term, env)?.to_i64(env).ok_or(CodecError::IntegerOverflow)
}
}
impl<'id> Encoder<'id> for u64 {
fn encode(&self, env: impl Env<'id>) -> Result<AnyTerm<'id>, CodecError> {
Integer::from_u64(env, *self).encode(env)
}
}
impl<'id> Decoder<'id> for u64 {
fn decode(term: AnyTerm<'id>, env: impl Env<'id>) -> Result<Self, CodecError> {
Integer::decode(term, env)?.to_u64(env).ok_or(CodecError::IntegerOverflow)
}
}
impl<'id> Encoder<'id> for isize {
fn encode(&self, env: impl Env<'id>) -> Result<AnyTerm<'id>, CodecError> {
Integer::from_i64(env, *self as i64).encode(env)
}
}
impl<'id> Decoder<'id> for isize {
fn decode(term: AnyTerm<'id>, env: impl Env<'id>) -> Result<Self, CodecError> {
let val = Integer::decode(term, env)?.to_i64(env).ok_or(CodecError::IntegerOverflow)?;
Self::try_from(val).map_err(|_| CodecError::IntegerOverflow)
}
}
impl<'id> Encoder<'id> for usize {
fn encode(&self, env: impl Env<'id>) -> Result<AnyTerm<'id>, CodecError> {
Integer::from_u64(env, *self as u64).encode(env)
}
}
impl<'id> Decoder<'id> for usize {
fn decode(term: AnyTerm<'id>, env: impl Env<'id>) -> Result<Self, CodecError> {
let val = Integer::decode(term, env)?.to_u64(env).ok_or(CodecError::IntegerOverflow)?;
Self::try_from(val).map_err(|_| CodecError::IntegerOverflow)
}
}