rustmann 0.2.2

Rust/Tokio client for Riemann
use bytes::{BigEndian, BufMut, ByteOrder, BytesMut};
use protobuf::{parse_from_carllerche_bytes, Message};
use tokio::codec::{Decoder, Encoder};

use std::io;
use std::usize;

use crate::protos::riemann::Msg;

#[derive(Debug)]
pub struct MsgCodec;

impl Encoder for MsgCodec {
    type Item = Msg;
    type Error = io::Error;

    fn encode(&mut self, msg: Self::Item, buf: &mut BytesMut) -> io::Result<()> {
        let data = msg.write_to_bytes().map_err(io::Error::from)?;

        buf.reserve(4 + data.len());

        buf.put_u32_be(data.len() as u32);
        buf.put(&data);
        Ok(())
    }
}

impl Decoder for MsgCodec {
    type Item = Msg;
    type Error = io::Error;

    fn decode(&mut self, buf: &mut BytesMut) -> io::Result<Option<Self::Item>> {
        if buf.len() > 4 {
            let msg_len = BigEndian::read_u32(&buf.split_to(4)) as usize;

            if buf.len() >= msg_len {
                let msg = parse_from_carllerche_bytes::<Msg>(&buf.split_to(msg_len).into())
                    .map_err(io::Error::from)?;
                Ok(Some(msg))
            } else {
                Ok(None)
            }
        } else {
            Ok(None)
        }
    }
}