diff options
| -rw-r--r-- | src/error/mod.rs | 2 | ||||
| -rw-r--r-- | src/primitive/variant.rs | 128 | ||||
| -rw-r--r-- | src/serialize.rs | 52 |
3 files changed, 59 insertions, 123 deletions
diff --git a/src/error/mod.rs b/src/error/mod.rs index b415c98..7414062 100644 --- a/src/error/mod.rs +++ b/src/error/mod.rs @@ -8,6 +8,8 @@ pub enum ProtocolError { BoolOutOfRange, #[error("QVariant is not known")] UnknownVariant, + #[error("UserType is not known: {0}")] + UnknownUserType(String), #[error("wrong variant has been given")] WrongVariant, #[error("io error: {0}")] diff --git a/src/primitive/variant.rs b/src/primitive/variant.rs index 32757d9..41d20d2 100644 --- a/src/primitive/variant.rs +++ b/src/primitive/variant.rs @@ -206,92 +206,32 @@ impl Deserialize for Variant { let (_, qtype) = i32::parse(&b[0..4])?; let qtype = qtype as u32; - #[allow(unused_variables)] - let unknown: u8 = b[4]; + let _unknown: u8 = b[4]; let len = 5; match qtype { - VariantMap::TYPE => { - trace!(target: "primitive::Variant", "Parsing Variant: VariantMap"); - let (vlen, value) = VariantMap::parse(&b[len..])?; - return Ok((len + vlen, Variant::VariantMap(value))); - } - VariantList::TYPE => { - trace!(target: "primitive::Variant", "Parsing Variant: VariantList"); - let (vlen, value) = VariantList::parse(&b[len..])?; - return Ok((len + vlen, Variant::VariantList(value))); - } - char::TYPE => { - trace!(target: "primitive::Variant", "Parsing Variant: Char"); - let (vlen, value) = char::parse(&b[len..])?; - return Ok((len + vlen, Variant::char(value))); - } - String::TYPE => { - trace!(target: "primitive::Variant", "Parsing Variant: String"); - let (vlen, value) = String::parse(&b[len..])?; - return Ok((len + vlen, Variant::String(value.clone()))); - } + VariantMap::TYPE => return VariantMap::parse_variant(b, len), + VariantList::TYPE => return VariantList::parse_variant(b, len), + char::TYPE => return char::parse_variant(b, len), + String::TYPE => String::parse_variant(b, len), primitive::QBYTEARRAY => { trace!(target: "primitive::Variant", "Parsing Variant: ByteArray"); let (vlen, value) = String::parse_utf8(&b[len..])?; return Ok((len + vlen, Variant::ByteArray(value.clone()))); } - StringList::TYPE => { - trace!(target: "primitive::Variant", "Parsing Variant: StringList"); - let (vlen, value) = StringList::parse(&b[len..])?; - return Ok((len + vlen, Variant::StringList(value.clone()))); - } - DateTime::TYPE => { - trace!(target: "primitive::Variant", "Parsing Variant: DateTime"); - let (vlen, value): (usize, DateTime) = Deserialize::parse(&b[len..])?; - return Ok((len + vlen, Variant::DateTime(value.clone()))); - } - Date::TYPE => { - trace!(target: "primitive::Variant", "Parsing Variant: Date"); - let (vlen, value): (usize, Date) = Deserialize::parse(&b[len..])?; - return Ok((len + vlen, Variant::Date(value.clone()))); - } - Time::TYPE => { - trace!(target: "primitive::Variant", "Parsing Variant: Time"); - let (vlen, value): (usize, Time) = Deserialize::parse(&b[len..])?; - return Ok((len + vlen, Variant::Time(value.clone()))); - } - bool::TYPE => { - let (vlen, value) = bool::parse(&b[len..])?; - return Ok((len + vlen, Variant::bool(value))); - } - u64::TYPE => { - let (vlen, value) = u64::parse(&b[len..])?; - return Ok((len + vlen, Variant::u64(value))); - } - u32::TYPE => { - let (vlen, value) = u32::parse(&b[len..])?; - return Ok((len + vlen, Variant::u32(value))); - } - u16::TYPE => { - let (vlen, value) = u16::parse(&b[len..])?; - return Ok((len + vlen, Variant::u16(value))); - } - u8::TYPE => { - let (vlen, value) = u8::parse(&b[len..])?; - return Ok((len + vlen, Variant::u8(value))); - } - i64::TYPE => { - let (vlen, value) = i64::parse(&b[len..])?; - return Ok((len + vlen, Variant::i64(value))); - } - i32::TYPE => { - let (vlen, value) = i32::parse(&b[len..])?; - return Ok((len + vlen, Variant::i32(value))); - } - i16::TYPE => { - let (vlen, value) = i16::parse(&b[len..])?; - return Ok((len + vlen, Variant::i16(value))); - } - i8::TYPE => { - let (vlen, value) = i8::parse(&b[len..])?; - return Ok((len + vlen, Variant::i8(value))); - } + StringList::TYPE => StringList::parse_variant(b, len), + DateTime::TYPE => DateTime::parse_variant(b, len), + Date::TYPE => Date::parse_variant(b, len), + Time::TYPE => Time::parse_variant(b, len), + bool::TYPE => bool::parse_variant(b, len), + u64::TYPE => u64::parse_variant(b, len), + u32::TYPE => u32::parse_variant(b, len), + u16::TYPE => u16::parse_variant(b, len), + u8::TYPE => u8::parse_variant(b, len), + i64::TYPE => i64::parse_variant(b, len), + i32::TYPE => i32::parse_variant(b, len), + i16::TYPE => i16::parse_variant(b, len), + i8::TYPE => i8::parse_variant(b, len), primitive::USERTYPE => { trace!(target: "primitive::Variant", "Parsing UserType"); // Parse UserType name @@ -302,11 +242,7 @@ impl Deserialize for Variant { // TODO implement all these types // Match Possible User Types to basic structures match user_type.as_str() { - "BufferId" => { - trace!(target: "primitive::Variant", "UserType is BufferId"); - let (vlen, value) = BufferId::parse(&b[(len + user_type_len)..])?; - return Ok((len + user_type_len + vlen, Variant::BufferId(value))); - } + BufferId::NAME => BufferId::parse_variant(b, len + user_type_len), // As VariantMap "IrcUser" | "IrcChannel" | "Identity" | "NetworkInfo" | "Network::Server" => { trace!(target: "primitive::Variant", "UserType is VariantMap"); @@ -320,27 +256,11 @@ impl Deserialize for Variant { let (vlen, value) = i32::parse(&b[(len + user_type_len)..])?; return Ok((len + user_type_len + vlen, Variant::i32(value))); } - PeerPtr::NAME => { - trace!(target: "primitive::Variant", "UserType is PeerPtr"); - let (vlen, value) = PeerPtr::parse(&b[(len + user_type_len)..])?; - return Ok((len + user_type_len + vlen, Variant::PeerPtr(value))); - } - "BufferInfo" => { - trace!(target: "primitive::Variant", "UserType is BufferInfo"); - let (vlen, value) = BufferInfo::parse(&b[(len + user_type_len)..])?; - return Ok((len + user_type_len + vlen, Variant::BufferInfo(value))); - } - "Message" => { - trace!(target: "primitive::Variant", "UserType is Message"); - let (vlen, value) = Message::parse(&b[(len + user_type_len)..])?; - return Ok((len + user_type_len + vlen, Variant::Message(value))); - } - "MsgId" => { - trace!(target: "primitive::Variant", "UserType is MsgId"); - let (vlen, value) = MsgId::parse(&b[(len + user_type_len)..])?; - return Ok((len + user_type_len + vlen, Variant::MsgId(value))); - } - _ => unimplemented!(), + PeerPtr::NAME => PeerPtr::parse_variant(b, len + user_type_len), + BufferInfo::NAME => BufferInfo::parse_variant(b, len + user_type_len), + Message::NAME => Message::parse_variant(b, len + user_type_len), + MsgId::NAME => MsgId::parse_variant(b, len + user_type_len), + _ => Err(ProtocolError::UnknownUserType(user_type)), } } err => { diff --git a/src/serialize.rs b/src/serialize.rs index 553a239..925b668 100644 --- a/src/serialize.rs +++ b/src/serialize.rs @@ -1,14 +1,7 @@ -use crate::{error::ProtocolError, primitive}; - -/// Serialization of types and structs to the quassel byteprotocol -pub trait Serialize { - fn serialize(&self) -> Result<Vec<u8>, ProtocolError>; -} - -/// Serialization of UTF-8 based Strings to the quassel byteprotocol -pub trait SerializeUTF8 { - fn serialize_utf8(&self) -> Result<Vec<u8>, ProtocolError>; -} +use crate::{ + error::ProtocolError, + primitive::{self, Variant}, +}; /// Sets the usertype name to be used in serialization and deserialization of the types variants. /// Automaticly implements the [SerializeVariant] trait. @@ -37,6 +30,24 @@ pub trait UserType { const NAME: &str; } +impl<T: UserType> VariantType for T { + const TYPE: u32 = primitive::USERTYPE; +} + +// ============================================= +// Serialization +// + +/// Serialization of types and structs to the quassel byteprotocol +pub trait Serialize { + fn serialize(&self) -> Result<Vec<u8>, ProtocolError>; +} + +/// Serialization of UTF-8 based Strings to the quassel byteprotocol +pub trait SerializeUTF8 { + fn serialize_utf8(&self) -> Result<Vec<u8>, ProtocolError>; +} + /// Provides a easy default implementation for serializing a type to it's [Variant] given it's QT type id. /// /// If the type is a UserType implement only [UserType], SerializeVariant is implemented automaticly. @@ -73,10 +84,6 @@ pub trait SerializeVariant: VariantType + Serialize { impl<T: VariantType + Serialize> SerializeVariant for T {} -impl<T: UserType> VariantType for T { - const TYPE: u32 = primitive::USERTYPE; -} - // ============================================= // Deserialization // @@ -95,8 +102,15 @@ pub trait DeserializeUTF8 { Self: std::marker::Sized; } -pub trait DeserializeVariant: VariantType { - fn parse_variant(b: &[u8]) -> Result<(usize, Self), ProtocolError> - where - Self: std::marker::Sized; +pub trait DeserializeVariant: VariantType + Deserialize +where + Variant: From<Self>, + Self: Sized, +{ + fn parse_variant(b: &[u8], len: usize) -> Result<(usize, Variant), ProtocolError> { + let (vlen, value) = Self::parse(&b[len..])?; + return Ok((len + vlen, value.into())); + } } + +impl<T: VariantType + Deserialize> DeserializeVariant for T where Variant: From<T> {} |
