From 8a4eac82fb2a452bb77500c6e071ad5e6f53c1cd Mon Sep 17 00:00:00 2001 From: Victor Koenders Date: Sun, 19 Sep 2021 08:28:38 +0200 Subject: [PATCH] Made the encoder respect intencoding, implemented FixintEncoding --- src/config.rs | 20 +++---- src/enc/impls.rs | 125 ++++++++++++++++++++++++++++++++++++++++++++ src/enc/mod.rs | 96 +++++++++++++++++++++++----------- src/int_encoding.rs | 116 +++++++++++++++++++++++++++++++++++++++- 4 files changed, 316 insertions(+), 41 deletions(-) diff --git a/src/config.rs b/src/config.rs index 751146b..31f90d1 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,19 +1,26 @@ +use crate::int_encoding::FixintEncoding; + pub(crate) use self::internal::*; pub trait Config: InternalConfig + Sized {} pub struct Default; -impl InternalConfig for Default {} +impl InternalConfig for Default { + type IntEncoding = FixintEncoding; +} impl Config for T {} mod internal { + use crate::int_encoding::IntEncoding; + pub trait InternalConfig { const ENDIAN: Endian = Endian::Little; - const INT_ENCODING: IntEncoding = IntEncoding::Variable; const LIMIT: Option = None; const ALLOW_TRAILING: bool = true; + + type IntEncoding: IntEncoding; } #[derive(PartialEq, Eq)] @@ -22,16 +29,11 @@ mod internal { Big, } - #[derive(PartialEq, Eq)] - pub enum IntEncoding { - Fixed, - Variable, - } - impl<'a, C: InternalConfig> InternalConfig for &'a mut C { const ENDIAN: Endian = C::ENDIAN; - const INT_ENCODING: IntEncoding = C::INT_ENCODING; const LIMIT: Option = C::LIMIT; const ALLOW_TRAILING: bool = C::ALLOW_TRAILING; + + type IntEncoding = C::IntEncoding; } } diff --git a/src/enc/impls.rs b/src/enc/impls.rs index da16aa2..cb800a9 100644 --- a/src/enc/impls.rs +++ b/src/enc/impls.rs @@ -7,14 +7,139 @@ impl Encodeable for u8 { } } +impl Encodeable for u16 { + fn encode(&self, mut encoder: E) -> Result<(), Error> { + encoder.encode_u16(*self) + } +} + impl Encodeable for u32 { fn encode(&self, mut encoder: E) -> Result<(), Error> { encoder.encode_u32(*self) } } +impl Encodeable for u64 { + fn encode(&self, mut encoder: E) -> Result<(), Error> { + encoder.encode_u64(*self) + } +} + +impl Encodeable for u128 { + fn encode(&self, mut encoder: E) -> Result<(), Error> { + encoder.encode_u128(*self) + } +} + +impl Encodeable for usize { + fn encode(&self, mut encoder: E) -> Result<(), Error> { + encoder.encode_usize(*self) + } +} + +impl Encodeable for i8 { + fn encode(&self, mut encoder: E) -> Result<(), Error> { + encoder.encode_i8(*self) + } +} + +impl Encodeable for i16 { + fn encode(&self, mut encoder: E) -> Result<(), Error> { + encoder.encode_i16(*self) + } +} + impl Encodeable for i32 { fn encode(&self, mut encoder: E) -> Result<(), Error> { encoder.encode_i32(*self) } } + +impl Encodeable for i64 { + fn encode(&self, mut encoder: E) -> Result<(), Error> { + encoder.encode_i64(*self) + } +} + +impl Encodeable for i128 { + fn encode(&self, mut encoder: E) -> Result<(), Error> { + encoder.encode_i128(*self) + } +} + +impl Encodeable for isize { + fn encode(&self, mut encoder: E) -> Result<(), Error> { + encoder.encode_isize(*self) + } +} + +impl Encodeable for f32 { + fn encode(&self, mut encoder: E) -> Result<(), Error> { + encoder.encode_f32(*self) + } +} + +impl Encodeable for f64 { + fn encode(&self, mut encoder: E) -> Result<(), Error> { + encoder.encode_f64(*self) + } +} + +impl Encodeable for &'_ [u8] { + fn encode(&self, mut encoder: E) -> Result<(), Error> { + encoder.encode_blob(*self) + } +} + +impl<'a, T> Encode for &'a mut T +where + T: Encode, +{ + fn encode_u8(&mut self, val: u8) -> Result<(), Error> { + T::encode_u8(self, val) + } + fn encode_u16(&mut self, val: u16) -> Result<(), Error> { + T::encode_u16(self, val) + } + fn encode_u32(&mut self, val: u32) -> Result<(), Error> { + T::encode_u32(self, val) + } + fn encode_u64(&mut self, val: u64) -> Result<(), Error> { + T::encode_u64(self, val) + } + fn encode_u128(&mut self, val: u128) -> Result<(), Error> { + T::encode_u128(self, val) + } + fn encode_usize(&mut self, val: usize) -> Result<(), Error> { + T::encode_usize(self, val) + } + + fn encode_i8(&mut self, val: i8) -> Result<(), Error> { + T::encode_i8(self, val) + } + fn encode_i16(&mut self, val: i16) -> Result<(), Error> { + T::encode_i16(self, val) + } + fn encode_i32(&mut self, val: i32) -> Result<(), Error> { + T::encode_i32(self, val) + } + fn encode_i64(&mut self, val: i64) -> Result<(), Error> { + T::encode_i64(self, val) + } + fn encode_i128(&mut self, val: i128) -> Result<(), Error> { + T::encode_i128(self, val) + } + fn encode_isize(&mut self, val: isize) -> Result<(), Error> { + T::encode_isize(self, val) + } + + fn encode_f32(&mut self, val: f32) -> Result<(), Error> { + T::encode_f32(self, val) + } + fn encode_f64(&mut self, val: f64) -> Result<(), Error> { + T::encode_f64(self, val) + } + fn encode_blob(&mut self, val: &[u8]) -> Result<(), Error> { + T::encode_blob(self, val) + } +} diff --git a/src/enc/mod.rs b/src/enc/mod.rs index e6c7100..4ac0329 100644 --- a/src/enc/mod.rs +++ b/src/enc/mod.rs @@ -1,9 +1,6 @@ use core::marker::PhantomData; -use crate::{ - config::{Config, Endian}, - error::Error, -}; +use crate::{config::Config, error::Error, int_encoding::IntEncoding}; use write::Writer; mod impls; @@ -12,25 +9,25 @@ pub mod write; pub trait Encodeable { fn encode(&self, encoder: E) -> Result<(), Error>; } + pub trait Encode { fn encode_u8(&mut self, val: u8) -> Result<(), Error>; + fn encode_u16(&mut self, val: u16) -> Result<(), Error>; fn encode_u32(&mut self, val: u32) -> Result<(), Error>; - fn encode_i32(&mut self, val: i32) -> Result<(), Error>; -} + fn encode_u64(&mut self, val: u64) -> Result<(), Error>; + fn encode_u128(&mut self, val: u128) -> Result<(), Error>; + fn encode_usize(&mut self, val: usize) -> Result<(), Error>; -impl<'a, T> Encode for &'a mut T -where - T: Encode, -{ - fn encode_u8(&mut self, val: u8) -> Result<(), Error> { - T::encode_u8(self, val) - } - fn encode_u32(&mut self, val: u32) -> Result<(), Error> { - T::encode_u32(self, val) - } - fn encode_i32(&mut self, val: i32) -> Result<(), Error> { - T::encode_i32(self, val) - } + fn encode_i8(&mut self, val: i8) -> Result<(), Error>; + fn encode_i16(&mut self, val: i16) -> Result<(), Error>; + fn encode_i32(&mut self, val: i32) -> Result<(), Error>; + fn encode_i64(&mut self, val: i64) -> Result<(), Error>; + fn encode_i128(&mut self, val: i128) -> Result<(), Error>; + fn encode_isize(&mut self, val: isize) -> Result<(), Error>; + + fn encode_f32(&mut self, val: f32) -> Result<(), Error>; + fn encode_f64(&mut self, val: f64) -> Result<(), Error>; + fn encode_blob(&mut self, val: &[u8]) -> Result<(), Error>; } pub struct Encoder { @@ -56,21 +53,60 @@ impl<'a, W: Writer, C: Config> Encode for &'a mut Encoder { self.writer.write(&[val]) } - fn encode_u32(&mut self, val: u32) -> Result<(), Error> { - let bytes = match C::ENDIAN { - Endian::Little => val.to_le_bytes(), - Endian::Big => val.to_be_bytes(), - }; + fn encode_u16(&mut self, val: u16) -> Result<(), Error> { + ::int_encode_u16(&mut self.writer, C::ENDIAN, val) + } - self.writer.write(&bytes) + fn encode_u32(&mut self, val: u32) -> Result<(), Error> { + ::int_encode_u32(&mut self.writer, C::ENDIAN, val) + } + + fn encode_u64(&mut self, val: u64) -> Result<(), Error> { + ::int_encode_u64(&mut self.writer, C::ENDIAN, val) + } + + fn encode_u128(&mut self, val: u128) -> Result<(), Error> { + ::int_encode_u128(&mut self.writer, C::ENDIAN, val) + } + + fn encode_usize(&mut self, val: usize) -> Result<(), Error> { + ::int_encode_usize(&mut self.writer, C::ENDIAN, val) + } + + fn encode_i8(&mut self, val: i8) -> Result<(), Error> { + self.writer.write(&[val as u8]) + } + + fn encode_i16(&mut self, val: i16) -> Result<(), Error> { + ::int_encode_i16(&mut self.writer, C::ENDIAN, val) } fn encode_i32(&mut self, val: i32) -> Result<(), Error> { - let bytes = match C::ENDIAN { - Endian::Little => val.to_le_bytes(), - Endian::Big => val.to_be_bytes(), - }; + ::int_encode_i32(&mut self.writer, C::ENDIAN, val) + } - self.writer.write(&bytes) + fn encode_i64(&mut self, val: i64) -> Result<(), Error> { + ::int_encode_i64(&mut self.writer, C::ENDIAN, val) + } + + fn encode_i128(&mut self, val: i128) -> Result<(), Error> { + ::int_encode_i128(&mut self.writer, C::ENDIAN, val) + } + + fn encode_isize(&mut self, val: isize) -> Result<(), Error> { + ::int_encode_isize(&mut self.writer, C::ENDIAN, val) + } + + fn encode_f32(&mut self, val: f32) -> Result<(), Error> { + ::int_encode_f32(&mut self.writer, C::ENDIAN, val) + } + + fn encode_f64(&mut self, val: f64) -> Result<(), Error> { + ::int_encode_f64(&mut self.writer, C::ENDIAN, val) + } + + fn encode_blob(&mut self, val: &[u8]) -> Result<(), Error> { + // TODO: Should this be swapped if we're big or little endian? + self.writer.write(val) } } diff --git a/src/int_encoding.rs b/src/int_encoding.rs index f3117ed..ba6622e 100644 --- a/src/int_encoding.rs +++ b/src/int_encoding.rs @@ -1,8 +1,120 @@ -use crate::{enc::write::Writer, error::Error}; +use crate::{config::Endian, enc::write::Writer, error::Error}; pub trait IntEncoding { - fn encode_u32(writer: &mut W, val: u32) -> Result<(), Error>; + fn int_encode_u16(writer: &mut W, endian: Endian, val: u16) -> Result<(), Error>; + fn int_encode_u32(writer: &mut W, endian: Endian, val: u32) -> Result<(), Error>; + fn int_encode_u64(writer: &mut W, endian: Endian, val: u64) -> Result<(), Error>; + fn int_encode_u128(writer: &mut W, endian: Endian, val: u128) -> Result<(), Error>; + fn int_encode_usize(writer: &mut W, endian: Endian, val: usize) + -> Result<(), Error>; + + fn int_encode_i16(writer: &mut W, endian: Endian, val: i16) -> Result<(), Error>; + fn int_encode_i32(writer: &mut W, endian: Endian, val: i32) -> Result<(), Error>; + fn int_encode_i64(writer: &mut W, endian: Endian, val: i64) -> Result<(), Error>; + fn int_encode_i128(writer: &mut W, endian: Endian, val: i128) -> Result<(), Error>; + fn int_encode_isize(writer: &mut W, endian: Endian, val: isize) + -> Result<(), Error>; + + fn int_encode_f32(writer: &mut W, endian: Endian, val: f32) -> Result<(), Error>; + fn int_encode_f64(writer: &mut W, endian: Endian, val: f64) -> Result<(), Error>; } +#[derive(Copy, Clone)] +pub struct VarintEncoding; + #[derive(Copy, Clone)] pub struct FixintEncoding; + +impl IntEncoding for FixintEncoding { + fn int_encode_u16(writer: &mut W, endian: Endian, val: u16) -> Result<(), Error> { + match endian { + Endian::Big => writer.write(&val.to_be_bytes()), + Endian::Little => writer.write(&val.to_le_bytes()), + } + } + + fn int_encode_u32(writer: &mut W, endian: Endian, val: u32) -> Result<(), Error> { + match endian { + Endian::Big => writer.write(&val.to_be_bytes()), + Endian::Little => writer.write(&val.to_le_bytes()), + } + } + + fn int_encode_u64(writer: &mut W, endian: Endian, val: u64) -> Result<(), Error> { + match endian { + Endian::Big => writer.write(&val.to_be_bytes()), + Endian::Little => writer.write(&val.to_le_bytes()), + } + } + + fn int_encode_u128(writer: &mut W, endian: Endian, val: u128) -> Result<(), Error> { + match endian { + Endian::Big => writer.write(&val.to_be_bytes()), + Endian::Little => writer.write(&val.to_le_bytes()), + } + } + + fn int_encode_usize( + writer: &mut W, + endian: Endian, + val: usize, + ) -> Result<(), Error> { + match endian { + Endian::Big => writer.write(&val.to_be_bytes()), + Endian::Little => writer.write(&val.to_le_bytes()), + } + } + + fn int_encode_i16(writer: &mut W, endian: Endian, val: i16) -> Result<(), Error> { + match endian { + Endian::Big => writer.write(&val.to_be_bytes()), + Endian::Little => writer.write(&val.to_le_bytes()), + } + } + + fn int_encode_i32(writer: &mut W, endian: Endian, val: i32) -> Result<(), Error> { + match endian { + Endian::Big => writer.write(&val.to_be_bytes()), + Endian::Little => writer.write(&val.to_le_bytes()), + } + } + + fn int_encode_i64(writer: &mut W, endian: Endian, val: i64) -> Result<(), Error> { + match endian { + Endian::Big => writer.write(&val.to_be_bytes()), + Endian::Little => writer.write(&val.to_le_bytes()), + } + } + + fn int_encode_i128(writer: &mut W, endian: Endian, val: i128) -> Result<(), Error> { + match endian { + Endian::Big => writer.write(&val.to_be_bytes()), + Endian::Little => writer.write(&val.to_le_bytes()), + } + } + + fn int_encode_isize( + writer: &mut W, + endian: Endian, + val: isize, + ) -> Result<(), Error> { + match endian { + Endian::Big => writer.write(&val.to_be_bytes()), + Endian::Little => writer.write(&val.to_le_bytes()), + } + } + + fn int_encode_f32(writer: &mut W, endian: Endian, val: f32) -> Result<(), Error> { + match endian { + Endian::Big => writer.write(&val.to_be_bytes()), + Endian::Little => writer.write(&val.to_le_bytes()), + } + } + + fn int_encode_f64(writer: &mut W, endian: Endian, val: f64) -> Result<(), Error> { + match endian { + Endian::Big => writer.write(&val.to_be_bytes()), + Endian::Little => writer.write(&val.to_le_bytes()), + } + } +}