use ::{Encoded, TempBuffer};
use ::bytes;
use ::error::{Result};
use core::marker::PhantomData;
use core::mem::size_of;
use serde::Serialize;
use serde::de::DeserializeOwned;
use ssmarshal;
#[cfg(feature = "use_std")]
use std::io::{Read, Write};
pub struct Codec<T: DeserializeOwned + Serialize> {
bytes_codec: bytes::Codec,
_phantom: PhantomData<T>,
}
pub struct Config<T: DeserializeOwned + Serialize> {
bytes_config: bytes::Config,
_phantom: PhantomData<T>,
}
impl<T: DeserializeOwned + Serialize> Clone for Config<T> {
fn clone(&self) -> Config<T> {
Config::<T> {
bytes_config: self.bytes_config.clone(),
_phantom: PhantomData::<T>::default(),
}
}
}
impl<T: DeserializeOwned + Serialize> Config<T> {
pub(crate) fn new(bytes_config: &bytes::Config) -> Config<T> {
Config::<T> {
bytes_config: bytes_config.clone(),
_phantom: PhantomData::<T>::default(),
}
}
pub fn to_codec(&mut self) -> Codec<T> {
Codec::<T> {
bytes_codec: self.bytes_config.to_codec(),
_phantom: PhantomData::<T>::default(),
}
}
#[cfg(feature = "use_std")]
pub fn to_receiver<R: Read>(&mut self, r: R) -> Receiver<R, T> {
Receiver::<R, T> {
codec: self.to_codec(),
r: r,
}
}
#[cfg(feature = "use_std")]
pub fn to_sender<W: Write>(&mut self, w: W) -> Sender<W, T> {
Sender::<W, T> {
codec: self.to_codec(),
w: w,
}
}
}
impl<T: DeserializeOwned + Serialize> Codec<T> {
pub fn encode_to_slice(
&mut self,
v: &T,
ser_buf: &mut TempBuffer,
dest: &mut Encoded,
) -> Result<usize> {
assert!(ser_buf.len() >= max_serialize_buf_len::<T>());
assert!(dest.len() >= max_encoded_len::<T>());
let ser_len = ssmarshal::serialize(ser_buf, v)?;
let ser = &ser_buf[0..ser_len];
self.bytes_codec.encode_to_slice(ser, dest)
}
pub fn decode_from_slice(
&mut self,
e: &Encoded,
de_buf: &mut TempBuffer
) -> Result<T> {
assert!(de_buf.len() >= max_serialize_buf_len::<T>());
let de_len = self.bytes_codec.decode_to_slice(e, de_buf)?;
let payload = &de_buf[0..de_len];
let (v, _len) = ssmarshal::deserialize(payload)?;
Ok(v)
}
}
const_fn! {
pub fn max_encoded_len<T: Serialize>() -> usize {
bytes::max_encoded_len(max_serialize_buf_len::<T>())
}
}
const_fn! {
pub fn max_serialize_buf_len<T: Serialize>() -> usize {
bytes::max_encoded_len(size_of::<T>())
}
}
#[cfg(feature = "use_std")]
pub struct Sender<W: Write, T: DeserializeOwned + Serialize> {
codec: Codec<T>,
w: W,
}
#[cfg(feature = "use_std")]
impl<W: Write, T: DeserializeOwned + Serialize> Sender<W, T> {
pub fn into_inner(self) -> W {
self.w
}
pub fn flush(&mut self) -> Result<()> {
Ok(self.w.flush()?)
}
pub fn queue(&mut self, v: &T) -> Result<usize> {
let mut ser_buf = vec![0u8; max_serialize_buf_len::<T>()];
let ser_len = ssmarshal::serialize(&mut ser_buf, v)?;
let ser = &ser_buf[0..ser_len];
self.codec.bytes_codec.encode_to_writer(&ser, &mut self.w)
}
pub fn send(&mut self, v: &T) -> Result<usize> {
let len = self.queue(v)?;
self.flush()?;
Ok(len)
}
}
#[cfg(feature = "use_std")]
pub struct Receiver<R: Read, T: DeserializeOwned + Serialize> {
codec: Codec<T>,
r: R,
}
#[cfg(feature = "use_std")]
impl<R: Read, T: DeserializeOwned + Serialize> Receiver<R, T> {
pub fn into_inner(self) -> R {
self.r
}
pub fn recv(&mut self) -> Result<T> {
let payload =
self.codec.bytes_codec.decode_from_reader::<R>(&mut self.r)?;
let (v, _len) = ssmarshal::deserialize(&*payload)?;
Ok(v)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[derive(Debug, Deserialize, Eq, PartialEq, Serialize)]
struct Test {
i8: i8,
i16: i16,
i32: i32,
i64: i64,
u8: u8,
u16: u16,
u32: u32,
u64: u64,
some: Option<u8>,
none: Option<u8>,
a: [u8; 3],
}
fn test_val() -> Test {
let v = Test {
i8: 1,
i16: 2,
i32: 3,
i64: 4,
u8: 10,
u16: 11,
u32: 12,
u64: 13,
some: Some(17),
none: None,
a: [1, 2, 3],
};
#[cfg(feature = "use_std")] {
println!("Test value: {:#?}", v);
}
v
}
fn codec() -> Codec<Test> {
bytes::Config::default().typed::<Test>().to_codec()
}
mod slice_tests {
use super::*;
#[test]
#[cfg(feature = "use_nightly")]
fn roundtrip() {
let input = test_val();
let mut c = codec();
let mut ser_buf = [0u8; max_serialize_buf_len::<Test>()];
let mut enc_buf = [0u8; max_encoded_len::<Test>()];
let len = c.encode_to_slice(
&input, &mut ser_buf, &mut enc_buf
).unwrap();
let enc = &enc_buf[0..len];
let output = c.decode_from_slice(&enc, &mut ser_buf).unwrap();
assert_eq!(input, output);
}
#[test]
#[should_panic]
fn bad_ser_buf_len() {
let mut ser_buf = [0u8; 1];
let mut enc = [0u8; 100];
codec().encode_to_slice(
&test_val(), &mut ser_buf, &mut enc
).unwrap();
}
#[test]
#[should_panic]
fn bad_dest_len() {
let mut ser_buf = [0u8; 100];
let mut enc = [0u8; 1];
codec().encode_to_slice(
&test_val(), &mut ser_buf, &mut enc
).unwrap();
}
}
mod len_tests {
use super::*;
#[test]
fn serialize_buf_len() {
assert_eq!(max_serialize_buf_len::<Test>(), 44);
assert_eq!(max_serialize_buf_len::<u8>(), 5);
assert_eq!(max_serialize_buf_len::<u16>(), 6);
assert_eq!(max_serialize_buf_len::<u32>(), 8);
assert_eq!(max_serialize_buf_len::<u64>(), 12);
}
#[test]
fn encoded_len() {
assert_eq!(max_encoded_len::<Test>(), 48);
assert_eq!(max_encoded_len::<u8>(), 9);
}
}
#[cfg(feature = "use_std")]
mod rw_tests {
use channel::Channel;
use error::Error;
use std::io::{Read, Write};
use super::*;
#[test]
fn one() {
let (mut tx, mut rx) = pair();
let v = test_val();
tx.send(&v).unwrap();
let r = rx.recv().unwrap();
println!("r: {:#?}", r);
assert_eq!(v, r);
}
#[test]
fn empty_input() {
let (mut _tx, mut rx) = pair();
match rx.recv() {
Err(Error::EofBeforeFrame) => (),
e @ _ => panic!("Bad value: {:?}", e)
}
}
fn pair() -> (Sender<Box<Write>, Test>, Receiver<Box<Read>, Test>) {
let chan = Channel::new();
let conf = bytes::Config::default().typed::<Test>();
let tx = conf.clone()
.to_sender(Box::new(chan.writer()) as Box<Write>);
let rx = conf.clone()
.to_receiver(Box::new(chan.reader()) as Box<Read>);
(tx, rx)
}
}
}