#![warn(missing_docs)]
#[macro_use]
extern crate serde_derive;
extern crate serde_cbor;
extern crate serde_bytes;
extern crate byteorder;
extern crate siphasher;
use std::io::Cursor;
use byteorder::{BigEndian, WriteBytesExt, ReadBytesExt};
use siphasher::sip::SipHasher;
use std::hash::{Hash, Hasher};
use std::net::SocketAddr;
use std::net::IpAddr;
const HDRL: usize = 4; const KEYL: usize = 8; const HDRKEYL: usize = HDRL + KEYL;
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Msg {
uid: String,
channel: String,
#[serde(with = "serde_bytes")]
message: Vec<u8>,
}
impl Msg {
pub fn new(uid: String, channel: String, message: Vec<u8>) -> Msg {
Msg {
uid: uid,
channel: channel,
message: message
}
}
pub fn set_uid(mut self, uid: String) -> Msg {
self.uid = uid;
self
}
pub fn set_channel(mut self, channel: String) -> Msg {
self.channel = channel;
self
}
pub fn set_message(mut self, message: Vec<u8>) -> Msg {
self.message = message;
self
}
pub fn get_uid(&self) -> &String {
&self.uid
}
pub fn get_channel(&self) -> &String {
&self.channel
}
pub fn get_message(&self) -> &Vec<u8> {
&self.message
}
}
pub fn message_encode(msg: &Msg) -> Vec<u8> {
let encoded = serde_cbor::to_vec(msg);
match encoded {
Ok(encoded) => encoded,
Err(err) => {
println!("Error on encode: {}", err);
Vec::new()
}
}
}
pub fn message_decode(slice: &[u8]) -> Msg {
let value = serde_cbor::from_slice(slice);
match value {
Ok(value) => value,
Err(err) => {
println!("Error on decode: {}", err);
Msg { uid: "".to_string(), channel: "".to_string(), message: Vec::new() } }
}
}
pub fn read_hdr_type(hdr: &Vec<u8>) -> u32 {
if hdr.len() < HDRL {
return 0;
}
let mut buf = Cursor::new(&hdr[..]);
let num = buf.read_u32::<BigEndian>().unwrap();
num >> 24
}
pub fn read_hdr_len(hdr: &Vec<u8>) -> usize {
if hdr.len() < HDRL {
return 0;
}
let mut buf = Cursor::new(&hdr[..]);
let num = buf.read_u32::<BigEndian>().unwrap();
(num & 0xfff) as usize
}
pub fn write_hdr(len: usize) -> Vec<u8> {
let hdr = (('M' as u32) << 24) | len as u32;
let mut msgv = vec![];
msgv.write_u32::<BigEndian>(hdr).unwrap();
msgv
}
pub fn write_key(val: u64) -> Vec<u8> {
let key = val;
let mut msgv = vec![];
msgv.write_u64::<BigEndian>(key).unwrap();
msgv
}
pub fn write_hdr_with_key(len: usize, key: u64) -> Vec<u8> {
let mut hdrv = write_hdr(len);
hdrv.extend(write_key(key));
hdrv
}
pub fn read_key(keyv: &Vec<u8>) -> u64 {
if keyv.len() < KEYL {
return 0;
}
let mut buf = Cursor::new(&keyv[..]);
let num = buf.read_u64::<BigEndian>().unwrap();
num
}
pub fn read_key_from_hdr(keyv: &Vec<u8>) -> u64 {
if keyv.len() < HDRKEYL {
return 0;
}
let mut buf = Cursor::new(&keyv[HDRL..]);
let num = buf.read_u64::<BigEndian>().unwrap();
num
}
pub fn do_hash<T: Hash>(t: &Vec<T>) -> u64 {
let mut s = SipHasher::new();
for item in t {
item.hash(&mut s);
}
s.finish()
}
pub fn addr2str(addr: &SocketAddr) -> String {
let ipaddr = addr.ip();
match ipaddr {
IpAddr::V4(v4) => {
let v4oct = v4.octets();
let v4str = format!("{}.{}.{}.{}:{}",
v4oct[0], v4oct[1], v4oct[2], v4oct[3],
addr.port());
return v4str;
}
IpAddr::V6(v6) => {
let v6seg = v6.segments();
let v6str = format!("[{:x}:{:x}:{:x}:{:x}:{:x}:{:x}:{:x}:{:x}]:{}",
v6seg[0], v6seg[1], v6seg[2], v6seg[3],
v6seg[4], v6seg[5], v6seg[6], v6seg[7],
addr.port());
return v6str;
}
}
}
#[cfg(test)]
mod tests {
use std::net::SocketAddr;
use super::*;
#[test]
fn test_encode_decode_msg() {
let uid = "User".to_string();
let channel = "Channel".to_string();
let msg = "a test msg".to_string().into_bytes();
let orig_msg = Msg::new(uid, channel, msg);
let cbor_msg = message_encode(&orig_msg);
let decoded_msg = message_decode(&cbor_msg);
assert_eq!(decoded_msg.uid, orig_msg.uid);
assert_eq!(decoded_msg.channel, orig_msg.channel);
assert_eq!(decoded_msg.message, orig_msg.message);
}
#[test]
fn test_set_get_msg() {
let uid = "User".to_string();
let channel = "Channel".to_string();
let msg = "a test msg".to_string().into_bytes();
let orig_msg = Msg::new("".to_string(), channel.to_string(), Vec::new());
let orig_msg = orig_msg.set_uid(uid.clone());
let orig_msg = orig_msg.set_channel(channel.clone());
let orig_msg = orig_msg.set_message(msg.clone());
assert_eq!(&uid, orig_msg.get_uid());
assert_eq!(&channel, orig_msg.get_channel());
assert_eq!(&msg, orig_msg.get_message());
}
#[test]
fn test_hash() {
let addr = "127.0.0.1:8077";
let addr = addr.parse::<SocketAddr>().unwrap();
let orig_key = do_hash(&vec![addr]);
let keyv = write_key(orig_key);
let key = read_key(&keyv);
assert_eq!(orig_key, key);
}
}