1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
use byteorder::{BigEndian, WriteBytesExt}; use crate::marker::Marker; use std::collections::BTreeMap; use std::io::Write; #[derive(Debug)] pub enum SerializeError { FailedToWrite, OutOfRange, } pub trait Serializable: Sized { fn serialize(self) -> Result<Vec<u8>, SerializeError>; fn serialize_string(v: String) -> Result<Vec<u8>, SerializeError> { let mut w = match v.len() { len if len <= 31 => { let mut w = Vec::with_capacity(1 + len); w.write_u8(Marker::FixStr(len as u8).into()).or(Err(SerializeError::FailedToWrite))?; w }, len if u8::max_value() as usize >= len => { let mut w = Vec::with_capacity(1 + 1 + len); w.write_u8(Marker::Str8.into()).or(Err(SerializeError::FailedToWrite))?; w.write_u8(len as u8).or(Err(SerializeError::FailedToWrite))?; w }, len if u16::max_value() as usize >= len => { let mut w = Vec::with_capacity(1 + 2 + len); w.write_u8(Marker::Str16.into()).or(Err(SerializeError::FailedToWrite))?; w.write_u16::<BigEndian>(len as u16).or(Err(SerializeError::FailedToWrite))?; w }, len if u32::max_value() as usize >= len => { let mut w = Vec::with_capacity(1 + 4 + len); w.write_u8(Marker::Str32.into()).or(Err(SerializeError::FailedToWrite))?; w.write_u32::<BigEndian>(len as u32).or(Err(SerializeError::FailedToWrite))?; w }, _ => Err(SerializeError::OutOfRange)?, }; w.write_all(v.as_bytes()).or(Err(SerializeError::FailedToWrite))?; Ok(w) } fn serialize_array(v: Vec<Self>) -> Result<Vec<u8>, SerializeError> { let mut values = Vec::new(); let len = v.len(); for vv in v.into_iter() { values.append(&mut Self::serialize(vv)?); } let mut w = match len { len if len <= 15 => { let mut w = Vec::with_capacity(1 + values.len()); w.write_u8(Marker::FixArray(len as u8).into()).or(Err(SerializeError::FailedToWrite))?; w }, len if u16::max_value() as usize >= len => { let mut w = Vec::with_capacity(1 + 2 + values.len()); w.write_u8(Marker::Array16.into()).or(Err(SerializeError::FailedToWrite))?; w.write_u16::<BigEndian>(len as u16).or(Err(SerializeError::FailedToWrite))?; w }, len if u32::max_value() as usize >= len => { let mut w = Vec::with_capacity(1 + 4 + values.len()); w.write_u8(Marker::Array32.into()).or(Err(SerializeError::FailedToWrite))?; w.write_u32::<BigEndian>(len as u32).or(Err(SerializeError::FailedToWrite))?; w }, _ => Err(SerializeError::OutOfRange)?, }; w.append(&mut values); Ok(w) } fn serialize_map(v: BTreeMap<String, Self>) -> Result<Vec<u8>, SerializeError> { let mut w = match v.len() { len if len <= 15 => { vec![Marker::FixMap(len as u8).into()] }, len if u16::max_value() as usize >= len => { let mut w = vec![Marker::Map16.into()]; w.write_u16::<BigEndian>(len as u16).or(Err(SerializeError::FailedToWrite))?; w }, len if u32::max_value() as usize >= len => { let mut w = vec![Marker::Map32.into()]; w.write_u32::<BigEndian>(len as u32).or(Err(SerializeError::FailedToWrite))?; w }, _ => Err(SerializeError::OutOfRange)?, }; for (k, v) in v { w.write_all(&Self::serialize_string(k)?).or(Err(SerializeError::FailedToWrite))?; w.write_all(&v.serialize()?).or(Err(SerializeError::FailedToWrite))?; } Ok(w) } }