zeromq 0.4.1

A native Rust implementation of ZeroMQ
Documentation
use bytes::Bytes;

use std::collections::vec_deque::{Iter, VecDeque};
use std::convert::{From, TryFrom};
use std::fmt;

#[derive(Debug)]
pub struct ZmqEmptyMessageError;

impl fmt::Display for ZmqEmptyMessageError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Unable to construct an empty ZmqMessage")
    }
}

#[derive(Debug, Clone)]
pub struct ZmqMessage {
    frames: VecDeque<Bytes>,
}

impl ZmqMessage {
    pub fn push_back(&mut self, frame: Bytes) {
        self.frames.push_back(frame);
    }

    pub fn push_front(&mut self, frame: Bytes) {
        self.frames.push_front(frame);
    }

    pub fn iter(&self) -> Iter<'_, Bytes> {
        self.frames.iter()
    }

    pub(crate) fn pop_front(&mut self) -> Option<Bytes> {
        self.frames.pop_front()
    }

    pub fn len(&self) -> usize {
        self.frames.len()
    }

    pub fn is_empty(&self) -> bool {
        self.frames.is_empty()
    }

    pub fn get(&self, index: usize) -> Option<&Bytes> {
        self.frames.get(index)
    }

    pub fn into_vec(self) -> Vec<Bytes> {
        Vec::from(self.frames)
    }

    pub fn into_vecdeque(self) -> VecDeque<Bytes> {
        self.frames
    }

    pub fn prepend(&mut self, message: &ZmqMessage) {
        for frame in message.iter().rev() {
            self.push_front(frame.clone());
        }
    }

    pub fn split_off(&mut self, at: usize) -> ZmqMessage {
        let frames = self.frames.split_off(at);
        ZmqMessage { frames }
    }
}

impl TryFrom<Vec<Bytes>> for ZmqMessage {
    type Error = ZmqEmptyMessageError;
    fn try_from(v: Vec<Bytes>) -> Result<Self, Self::Error> {
        if v.is_empty() {
            Err(ZmqEmptyMessageError)
        } else {
            Ok(Self { frames: v.into() })
        }
    }
}

impl TryFrom<VecDeque<Bytes>> for ZmqMessage {
    type Error = ZmqEmptyMessageError;
    fn try_from(v: VecDeque<Bytes>) -> Result<Self, Self::Error> {
        if v.is_empty() {
            Err(ZmqEmptyMessageError)
        } else {
            Ok(Self { frames: v })
        }
    }
}

impl From<Vec<u8>> for ZmqMessage {
    fn from(v: Vec<u8>) -> Self {
        ZmqMessage::from(Bytes::from(v))
    }
}

impl From<Bytes> for ZmqMessage {
    fn from(b: Bytes) -> Self {
        Self {
            frames: vec![b].into(),
        }
    }
}

impl From<String> for ZmqMessage {
    fn from(s: String) -> Self {
        let b: Bytes = s.into();
        ZmqMessage::from(b)
    }
}

impl From<&str> for ZmqMessage {
    fn from(s: &str) -> Self {
        ZmqMessage::from(s.to_owned())
    }
}

impl TryFrom<ZmqMessage> for Vec<u8> {
    type Error = &'static str;

    fn try_from(z: ZmqMessage) -> Result<Self, Self::Error> {
        if z.len() != 1 {
            return Err("Message must have only 1 frame to convert to Vec<u8>");
        }
        Ok(z.into_vecdeque().pop_front().unwrap().to_vec())
    }
}

impl TryFrom<ZmqMessage> for String {
    type Error = &'static str;

    fn try_from(z: ZmqMessage) -> Result<Self, Self::Error> {
        if z.len() != 1 {
            return Err("Message must have only 1 frame to convert to String");
        }
        match String::from_utf8(z.into_vecdeque().pop_front().unwrap().to_vec()) {
            Ok(s) => Ok(s),
            Err(_) => Err("Could not parse string from message"),
        }
    }
}