aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs58
-rw-r--r--src/message/handshake/connack.rs4
-rw-r--r--src/message/handshake/init.rs3
-rw-r--r--src/message/handshake/mod.rs4
-rw-r--r--src/message/handshake/protocol.rs3
-rw-r--r--src/message/handshake/sessioninit.rs33
-rw-r--r--src/message/handshake/types.rs5
-rw-r--r--src/message/signalproxy/heartbeat.rs2
-rw-r--r--src/message/signalproxy/initdata.rs18
-rw-r--r--src/message/signalproxy/initrequest.rs2
-rw-r--r--src/message/signalproxy/mod.rs6
-rw-r--r--src/message/signalproxy/objects/aliasmanager.rs131
-rw-r--r--src/message/signalproxy/objects/buffersyncer.rs263
-rw-r--r--src/message/signalproxy/objects/coreinfo.rs60
-rw-r--r--src/message/signalproxy/objects/highlightrulemanager.rs113
-rw-r--r--src/message/signalproxy/objects/identity.rs119
-rw-r--r--src/message/signalproxy/objects/ircchannel.rs245
-rw-r--r--src/message/signalproxy/objects/ircuser.rs53
-rw-r--r--src/message/signalproxy/objects/mod.rs59
-rw-r--r--src/message/signalproxy/objects/network.rs258
-rw-r--r--src/message/signalproxy/objects/networkinfo.rs18
-rw-r--r--src/message/signalproxy/rpccall.rs2
-rw-r--r--src/message/signalproxy/syncmessage.rs2
-rw-r--r--src/primitive/bufferinfo.rs3
-rw-r--r--src/primitive/datetime.rs3
-rw-r--r--src/primitive/message.rs8
-rw-r--r--src/primitive/signedint.rs2
-rw-r--r--src/primitive/string.rs10
-rw-r--r--src/primitive/stringlist.rs2
-rw-r--r--src/primitive/unsignedint.rs2
-rw-r--r--src/primitive/variant.rs30
-rw-r--r--src/primitive/variantlist.rs2
-rw-r--r--src/primitive/variantmap.rs7
33 files changed, 963 insertions, 567 deletions
diff --git a/src/lib.rs b/src/lib.rs
index a2a3a25..e2f57c9 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,3 +1,4 @@
+#![feature(test)]
#![feature(external_doc)]
#![feature(doc_cfg)]
#![doc(include = "../README.md")]
@@ -26,32 +27,51 @@ pub mod error;
/// Framing impl to be used with [`tokio_util::codec::Framed`]
pub mod frame;
-use failure::Error;
+/// Traits for Serialization of objects
+pub mod serialize {
+ use failure::Error;
-/// Serialization of types and structs to the quassel byteprotocol
-pub trait Serialize {
- fn serialize(&self) -> Result<Vec<u8>, Error>;
-}
+ /// Serialization of types and structs to the quassel byteprotocol
+ pub trait Serialize {
+ fn serialize(&self) -> Result<Vec<u8>, Error>;
+ }
-/// Serialization of UTF-8 based Strings to the quassel byteprotocol
-pub trait SerializeUTF8 {
- fn serialize_utf8(&self) -> Result<Vec<u8>, Error>;
-}
+ /// Serialization of UTF-8 based Strings to the quassel byteprotocol
+ pub trait SerializeUTF8 {
+ fn serialize_utf8(&self) -> Result<Vec<u8>, Error>;
+ }
-/// Deserialization of types and structs to the quassel byteprotocol
-pub trait Deserialize {
- fn parse(b: &[u8]) -> Result<(usize, Self), Error>
- where
- Self: std::marker::Sized;
+ pub trait SerializeVariant {
+ fn serialize_variant(&self) -> Result<Vec<u8>, Error>;
+ }
}
-/// Deserialization of UTF-8 based Strings to the quassel byteprotocol
-pub trait DeserializeUTF8 {
- fn parse_utf8(b: &[u8]) -> Result<(usize, Self), Error>
- where
- Self: std::marker::Sized;
+/// Traits for parsing objects
+pub mod deserialize {
+ use failure::Error;
+
+ /// Deserialization of types and structs to the quassel byteprotocol
+ pub trait Deserialize {
+ fn parse(b: &[u8]) -> Result<(usize, Self), Error>
+ where
+ Self: std::marker::Sized;
+ }
+
+ /// Deserialization of UTF-8 based Strings to the quassel byteprotocol
+ pub trait DeserializeUTF8 {
+ fn parse_utf8(b: &[u8]) -> Result<(usize, Self), Error>
+ where
+ Self: std::marker::Sized;
+ }
+
+ pub trait DeserializeVariant {
+ fn parse_variant(b: &[u8]) -> Result<(usize, Self), Error>
+ where
+ Self: std::marker::Sized;
+ }
}
+use failure::Error;
/// HandshakeSerialize implements the serialization needed during the handhake phase.
///
/// The protocol has some minor differences during this phase compared to the regular parsing.
diff --git a/src/message/handshake/connack.rs b/src/message/handshake/connack.rs
index 222c08c..a246679 100644
--- a/src/message/handshake/connack.rs
+++ b/src/message/handshake/connack.rs
@@ -29,7 +29,7 @@ impl Default for ConnAck {
}
}
-impl crate::Serialize for ConnAck {
+impl crate::serialize::Serialize for ConnAck {
fn serialize(&self) -> Result<Vec<std::primitive::u8>, Error> {
let mut bytes: Vec<u8> = Vec::new();
@@ -41,7 +41,7 @@ impl crate::Serialize for ConnAck {
}
}
-impl crate::Deserialize for ConnAck {
+impl crate::deserialize::Deserialize for ConnAck {
fn parse(b: &[u8]) -> Result<(usize, Self), Error> {
let (flen, flags) = u8::parse(b)?;
let (elen, extra) = i16::parse(&b[flen..])?;
diff --git a/src/message/handshake/init.rs b/src/message/handshake/init.rs
index b4604b6..df1b29e 100644
--- a/src/message/handshake/init.rs
+++ b/src/message/handshake/init.rs
@@ -1,5 +1,4 @@
-use crate::Deserialize;
-use crate::Serialize;
+use crate::{deserialize::Deserialize, serialize::Serialize};
/// The first few bytes sent to the core to initialize the connection and setup if we want to use tls and compression
#[derive(Clone, Debug)]
diff --git a/src/message/handshake/mod.rs b/src/message/handshake/mod.rs
index c180c5e..029eb86 100644
--- a/src/message/handshake/mod.rs
+++ b/src/message/handshake/mod.rs
@@ -24,7 +24,7 @@ pub use protocol::*;
pub use sessioninit::*;
pub use types::*;
-use crate::primitive::{Variant, VariantMap};
+use crate::primitive::VariantMap;
use crate::{HandshakeDeserialize, HandshakeSerialize};
#[derive(Debug, Clone)]
@@ -56,7 +56,7 @@ impl HandshakeDeserialize for HandshakeMessage {
fn parse(b: &[u8]) -> Result<(usize, Self), failure::Error> {
let (size, res) = VariantMap::parse(b)?;
- let msgtype = match_variant!(&res["MsgType"], Variant::String);
+ let msgtype: String = (&res["MsgType"]).into();
match msgtype.as_str() {
"ClientInit" => Ok((size, HandshakeMessage::ClientInit(res.into()))),
"ClientInitAck" => Ok((size, HandshakeMessage::ClientInitAck(res.into()))),
diff --git a/src/message/handshake/protocol.rs b/src/message/handshake/protocol.rs
index d020f33..c12da05 100644
--- a/src/message/handshake/protocol.rs
+++ b/src/message/handshake/protocol.rs
@@ -1,5 +1,4 @@
-use crate::Deserialize;
-use crate::Serialize;
+use crate::{deserialize::Deserialize, serialize::Serialize};
pub enum Protocol {
Legacy = 0x00000001,
diff --git a/src/message/handshake/sessioninit.rs b/src/message/handshake/sessioninit.rs
index d1b4b90..a663cce 100644
--- a/src/message/handshake/sessioninit.rs
+++ b/src/message/handshake/sessioninit.rs
@@ -1,3 +1,5 @@
+use std::convert::TryInto;
+
use crate::message::objects::Identity;
use crate::primitive::{BufferInfo, Variant, VariantMap};
use crate::HandshakeSerialize;
@@ -18,12 +20,15 @@ pub struct SessionInit {
impl From<VariantMap> for SessionInit {
fn from(input: VariantMap) -> Self {
- let state = match_variant!(input.get("SessionState").unwrap(), Variant::VariantMap);
+ use crate::message::signalproxy::Network;
+ let state: VariantMap = input.get("SessionState").unwrap().try_into().unwrap();
+
+ log::trace!("sessionstate: {:#?}", state);
+
SessionInit {
- identities: match_variant!(state.get("Identities").unwrap(), Variant::VariantList)
- .iter()
- .map(|ident| Identity::from(match_variant!(ident, Variant::VariantMap)))
- .collect(),
+ identities: Vec::<Identity>::from_network(
+ &mut state.get("Identities").unwrap().try_into().unwrap(),
+ ),
buffers: match_variant!(state.get("BufferInfos").unwrap(), Variant::VariantList)
.iter()
.map(|buffer| match buffer {
@@ -49,15 +54,15 @@ impl HandshakeSerialize for SessionInit {
"MsgType".to_string(),
Variant::String("SessionInit".to_string()),
);
- values.insert(
- "Identities".to_string(),
- Variant::VariantList(
- self.identities
- .iter()
- .map(|ident| Variant::VariantMap(ident.clone().into()))
- .collect(),
- ),
- );
+ // values.insert(
+ // "Identities".to_string(),
+ // Variant::VariantList(
+ // self.identities
+ // .iter()
+ // .map(|ident| Variant::VariantMap(ident.clone().into()))
+ // .collect(),
+ // ),
+ // );
values.insert(
"BufferInfos".to_string(),
Variant::VariantList(
diff --git a/src/message/handshake/types.rs b/src/message/handshake/types.rs
index 24d847b..e9e6469 100644
--- a/src/message/handshake/types.rs
+++ b/src/message/handshake/types.rs
@@ -7,11 +7,10 @@ use failure::Error;
use crate::error::ProtocolError;
use crate::primitive::Variant;
use crate::util;
-use crate::Deserialize;
-use crate::Serialize;
+use crate::{deserialize::Deserialize, serialize::Serialize};
+use crate::message::handshake::{HandshakeDeserialize, HandshakeSerialize};
use crate::primitive::VariantMap;
-use crate::{HandshakeDeserialize, HandshakeSerialize};
impl HandshakeSerialize for VariantMap {
fn serialize<'a>(&'a self) -> Result<Vec<u8>, Error> {
diff --git a/src/message/signalproxy/heartbeat.rs b/src/message/signalproxy/heartbeat.rs
index 46bfd51..58dc430 100644
--- a/src/message/signalproxy/heartbeat.rs
+++ b/src/message/signalproxy/heartbeat.rs
@@ -1,6 +1,6 @@
use crate::message::MessageType;
use crate::primitive::{DateTime, Variant, VariantList};
-use crate::{Deserialize, Serialize};
+use crate::{deserialize::Deserialize, serialize::Serialize};
#[derive(Clone, Debug, std::cmp::PartialEq)]
pub struct HeartBeat {
diff --git a/src/message/signalproxy/initdata.rs b/src/message/signalproxy/initdata.rs
index abeacad..7c3e443 100644
--- a/src/message/signalproxy/initdata.rs
+++ b/src/message/signalproxy/initdata.rs
@@ -1,12 +1,14 @@
use crate::message::MessageType;
use crate::primitive::{Variant, VariantList};
-use crate::{Deserialize, Serialize};
+use crate::{deserialize::Deserialize, serialize::Serialize};
+
+use super::objects::Types;
#[derive(Clone, Debug, std::cmp::PartialEq)]
pub struct InitData {
class_name: String,
object_name: String,
- init_data: VariantList,
+ init_data: Types,
}
impl Serialize for InitData {
@@ -17,24 +19,26 @@ impl Serialize for InitData {
res.push(Variant::ByteArray(self.class_name.clone()));
res.push(Variant::ByteArray(self.object_name.clone()));
- res.append(&mut self.init_data.clone());
+ res.append(&mut self.init_data.to_network());
res.serialize()
}
}
impl Deserialize for InitData {
- fn parse(b: &[std::primitive::u8]) -> Result<(std::primitive::usize, Self), failure::Error> {
+ fn parse(b: &[u8]) -> Result<(usize, Self), failure::Error> {
let (size, mut res) = VariantList::parse(&b)?;
res.remove(0);
+ let class_name: String = res.remove(0).into();
+
Ok((
size,
Self {
- class_name: match_variant!(res.remove(0), Variant::ByteArray),
- object_name: match_variant!(res.remove(0), Variant::ByteArray),
- init_data: res,
+ class_name: class_name.clone(),
+ object_name: res.remove(0).into(),
+ init_data: Types::from_network(class_name.as_str(), &mut res),
},
))
}
diff --git a/src/message/signalproxy/initrequest.rs b/src/message/signalproxy/initrequest.rs
index 5190e0a..1beef5c 100644
--- a/src/message/signalproxy/initrequest.rs
+++ b/src/message/signalproxy/initrequest.rs
@@ -1,6 +1,6 @@
use crate::message::MessageType;
use crate::primitive::{Variant, VariantList};
-use crate::{Deserialize, Serialize};
+use crate::{deserialize::Deserialize, serialize::Serialize};
#[derive(Clone, Debug, std::cmp::PartialEq)]
pub struct InitRequest {
diff --git a/src/message/signalproxy/mod.rs b/src/message/signalproxy/mod.rs
index 9887af7..2887407 100644
--- a/src/message/signalproxy/mod.rs
+++ b/src/message/signalproxy/mod.rs
@@ -1,4 +1,6 @@
-use crate::{Deserialize, Serialize};
+use crate::{deserialize::Deserialize, serialize::Serialize};
+
+use num_derive::{FromPrimitive, ToPrimitive};
mod heartbeat;
mod initdata;
@@ -98,7 +100,7 @@ impl Deserialize for Message {
/// Type of an SignalProxy Message
/// The first element in the VariantList that is received
#[repr(i32)]
-#[derive(Copy, Clone, Debug, std::cmp::PartialEq)]
+#[derive(Debug, Copy, Clone, PartialEq, FromPrimitive, ToPrimitive)]
pub enum MessageType {
/// Bidirectional
SyncMessage = 0x00000001,
diff --git a/src/message/signalproxy/objects/aliasmanager.rs b/src/message/signalproxy/objects/aliasmanager.rs
index 093163b..b536cde 100644
--- a/src/message/signalproxy/objects/aliasmanager.rs
+++ b/src/message/signalproxy/objects/aliasmanager.rs
@@ -1,93 +1,27 @@
-use crate::primitive::{StringList, Variant, VariantMap};
+use libquassel_derive::Network;
-use crate::message::signalproxy::Network;
-
-#[derive(Clone, Debug, std::cmp::PartialEq)]
+#[derive(Clone, Debug, std::cmp::PartialEq, Network)]
+#[network(repr = "list")]
pub struct AliasManager {
+ #[network(rename = "Aliases", variant = "VariantMap", network)]
pub aliases: Vec<Alias>,
}
-#[derive(Clone, Debug, std::cmp::PartialEq)]
+#[derive(Clone, Debug, std::cmp::PartialEq, Network)]
+#[network(repr = "maplist")]
pub struct Alias {
+ #[network(rename = "names", variant = "StringList")]
name: String,
+ #[network(rename = "expansions", variant = "StringList")]
expansion: String,
}
-impl Alias {
- fn from_network_internal(input: &VariantMap) -> Vec<Self> {
- let names = match_variant!(input.get("names").unwrap(), Variant::StringList);
- let expansions = match_variant!(input.get("expansions").unwrap(), Variant::StringList);
-
- return names
- .iter()
- .zip(expansions)
- .map(|(name, expansion)| Alias {
- name: name.clone(),
- expansion,
- })
- .collect();
- }
-}
-
-impl Network for Alias {
- type Item = VariantMap;
-
- fn to_network(&self) -> Self::Item {
- let mut map = VariantMap::new();
- map.insert(s!("names"), Variant::StringList(vec![self.name.clone()]));
- map.insert(
- s!("expansions"),
- Variant::StringList(vec![self.expansion.clone()]),
- );
-
- return map;
- }
-
- fn from_network(input: &mut Self::Item) -> Self {
- Alias::from_network_internal(&input)[0].clone()
- }
-}
-
-impl Network for AliasManager {
- type Item = VariantMap;
-
- fn to_network(&self) -> Self::Item {
- let (names, expansions) = self.aliases.iter().fold(
- (StringList::new(), StringList::new()),
- |(mut names, mut expansions), alias| {
- names.push(alias.name.clone());
- expansions.push(alias.expansion.clone());
- return (names, expansions);
- },
- );
-
- let mut map = VariantMap::new();
- map.insert(s!("names"), Variant::StringList(names));
- map.insert(s!("expansions"), Variant::StringList(expansions));
-
- return map;
- }
-
- fn from_network(input: &mut Self::Item) -> Self {
- let names = match_variant!(input.get("names").unwrap(), Variant::StringList);
- let expansions = match_variant!(input.get("expansions").unwrap(), Variant::StringList);
-
- AliasManager {
- aliases: names
- .iter()
- .zip(expansions)
- .map(|(name, expansion)| Alias {
- name: name.clone(),
- expansion,
- })
- .collect(),
- }
- }
-}
-
#[cfg(test)]
mod tests {
use super::*;
+ use crate::message::signalproxy::translation::Network;
+
+ use crate::primitive::{Variant, VariantList};
fn get_src() -> AliasManager {
AliasManager {
@@ -104,23 +38,36 @@ mod tests {
}
}
- fn get_dest() -> VariantMap {
- map! {
- s!("names") => Variant::StringList(
- vec![
- s!("j"),
- s!("ns"),
- ],
- ),
- s!("expansions") => Variant::StringList(
- vec![
- s!("/join $0"),
- s!("/msg nickserv $0"),
- ],
- ),
- }
+ fn get_dest() -> VariantList {
+ vec![
+ Variant::ByteArray(s!("Aliases")),
+ Variant::VariantMap(map! {
+ s!("names") => Variant::StringList(
+ vec![
+ s!("j"),
+ s!("ns"),
+ ],
+ ),
+ s!("expansions") => Variant::StringList(
+ vec![
+ s!("/join $0"),
+ s!("/msg nickserv $0"),
+ ],
+ ),
+ }),
+ ]
}
+ // #[bench]
+ // fn alias_to_network(b: &mut test::Bencher) {
+ // b.iter(|| test::black_box(get_src()).to_network())
+ // }
+
+ // #[bench]
+ // fn alias_from_network(b: &mut test::Bencher) {
+ // b.iter(|| AliasManager::from_network(&mut test::black_box(get_dest())))
+ // }
+
#[test]
fn aliasmanager_to_network() {
assert_eq!(get_src().to_network(), get_dest())
diff --git a/src/message/signalproxy/objects/buffersyncer.rs b/src/message/signalproxy/objects/buffersyncer.rs
index 7ee4ca5..cc26310 100644
--- a/src/message/signalproxy/objects/buffersyncer.rs
+++ b/src/message/signalproxy/objects/buffersyncer.rs
@@ -1,13 +1,148 @@
-use crate::message::signalproxy::MessageType;
-use std::collections::HashMap;
+use std::{collections::HashMap, convert::TryInto};
-// use default_macro::default;
-// #[default(crate::message::signalproxy::objects::BufferSyncerClient)]
+use num_traits::{FromPrimitive, ToPrimitive};
+
+use itertools::Itertools;
+
+use crate::{
+ message::signalproxy::Network,
+ primitive::{MessageType, Variant, VariantList},
+};
+
+#[derive(Debug, Clone, PartialEq)]
pub struct BufferSyncer {
- pub activities: HashMap<u32, MessageType>,
- pub highlight_counts: HashMap<u32, u32>,
- pub last_seen_msg: HashMap<u32, u32>,
- pub marker_line: HashMap<u32, u32>,
+ pub activities: HashMap<i32, MessageType>,
+ pub highlight_counts: HashMap<i32, i32>,
+ pub last_seen_msg: HashMap<i32, i64>,
+ pub marker_line: HashMap<i32, i64>,
+}
+
+impl Network for BufferSyncer {
+ type Item = VariantList;
+
+ fn to_network(&self) -> Self::Item {
+ let mut res = Self::Item::new();
+
+ res.push(Variant::ByteArray(s!("Activities")));
+ res.push(Variant::VariantList({
+ let mut res = VariantList::new();
+
+ self.activities.iter().for_each(|(k, v)| {
+ res.push(Variant::i32(*k));
+ res.push(Variant::i32(v.to_i32().unwrap()));
+ });
+
+ res
+ }));
+
+ res.push(Variant::ByteArray(s!("HighlightCounts")));
+ res.push(Variant::VariantList({
+ let mut res = VariantList::new();
+
+ self.highlight_counts.iter().for_each(|(k, v)| {
+ res.push(Variant::i32(*k));
+ res.push(Variant::i32(*v));
+ });
+
+ res
+ }));
+
+ res.push(Variant::ByteArray(s!("LastSeenMsg")));
+ res.push(Variant::VariantList({
+ let mut res = VariantList::new();
+
+ self.last_seen_msg.iter().for_each(|(k, v)| {
+ res.push(Variant::i32(*k));
+ res.push(Variant::i64(*v));
+ });
+
+ res
+ }));
+
+ res.push(Variant::ByteArray(s!("MarkerLines")));
+ res.push(Variant::VariantList({
+ let mut res = VariantList::new();
+
+ self.marker_line.iter().for_each(|(k, v)| {
+ res.push(Variant::i32(*k));
+ res.push(Variant::i64(*v));
+ });
+
+ res
+ }));
+
+ res
+ }
+
+ fn from_network(input: &mut Self::Item) -> Self {
+ let mut i = input.iter().cycle();
+
+ i.position(|x| *x == crate::primitive::Variant::ByteArray(s!("Activities")))
+ .unwrap();
+ let activities: VariantList = i.next().unwrap().try_into().unwrap();
+ let activities = activities
+ .iter()
+ .batching(|it| match it.next() {
+ None => None,
+ Some(x) => match it.next() {
+ None => None,
+ Some(y) => Some((
+ x.try_into().unwrap(),
+ MessageType::from_i32(y.try_into().unwrap()).unwrap(),
+ )),
+ },
+ })
+ .collect();
+
+ i.position(|x| *x == crate::primitive::Variant::ByteArray(s!("HighlightCounts")))
+ .unwrap();
+ let highlight_counts: VariantList = i.next().unwrap().try_into().unwrap();
+ let highlight_counts = highlight_counts
+ .iter()
+ .batching(|it| match it.next() {
+ None => None,
+ Some(x) => match it.next() {
+ None => None,
+ Some(y) => Some((x.try_into().unwrap(), y.try_into().unwrap())),
+ },
+ })
+ .collect();
+
+ i.position(|x| *x == crate::primitive::Variant::ByteArray(s!("LastSeenMsg")))
+ .unwrap();
+ let last_seen_msg: VariantList = i.next().unwrap().try_into().unwrap();
+ let last_seen_msg = last_seen_msg
+ .iter()
+ .batching(|it| match it.next() {
+ None => None,
+ Some(x) => match it.next() {
+ None => None,
+ Some(y) => Some((x.try_into().unwrap(), y.try_into().unwrap())),
+ },
+ })
+ .collect();
+
+ i.position(|x| *x == crate::primitive::Variant::ByteArray(s!("MarkerLines")))
+ .unwrap();
+ let marker_line: VariantList = i.next().unwrap().try_into().unwrap();
+ let marker_line = marker_line
+ .iter()
+ .batching(|it| match it.next() {
+ None => None,
+ Some(x) => match it.next() {
+ None => None,
+ Some(y) => Some((x.try_into().unwrap(), y.try_into().unwrap())),
+ },
+ })
+ .collect();
+
+ Self {
+ activities,
+ highlight_counts,
+ last_seen_msg,
+ marker_line,
+ }
+ }
}
pub trait BufferSyncerServer {
@@ -72,3 +207,115 @@ pub trait BufferSyncerClient {
self.marker_line_mut().insert(buffer, msgid);
}
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use crate::message::signalproxy::translation::Network;
+ use crate::primitive::{Variant, VariantList};
+ use pretty_assertions::assert_eq;
+
+ fn get_network() -> VariantList {
+ vec![
+ Variant::ByteArray(s!("Activities")),
+ Variant::VariantList(vec![
+ Variant::i32(1),
+ Variant::i32(0),
+ Variant::i32(2),
+ Variant::i32(0),
+ Variant::i32(3),
+ Variant::i32(0),
+ Variant::i32(4),
+ Variant::i32(0),
+ Variant::i32(5),
+ Variant::i32(0),
+ ]),
+ Variant::ByteArray(s!("HighlightCounts")),
+ Variant::VariantList(vec![
+ Variant::i32(1),
+ Variant::i32(0),
+ Variant::i32(2),
+ Variant::i32(0),
+ Variant::i32(3),
+ Variant::i32(0),
+ Variant::i32(4),
+ Variant::i32(0),
+ Variant::i32(5),
+ Variant::i32(0),
+ ]),
+ Variant::ByteArray(s!("LastSeenMsg")),
+ Variant::VariantList(vec![
+ Variant::i32(1),
+ Variant::i64(2185),
+ Variant::i32(2),
+ Variant::i64(2188),
+ Variant::i32(3),
+ Variant::i64(860),
+ Variant::i32(4),
+ Variant::i64(2183),
+ Variant::i32(5),
+ Variant::i64(2180),
+ ]),
+ Variant::ByteArray(s!("MarkerLines")),
+ Variant::VariantList(vec![
+ Variant::i32(1),
+ Variant::i64(2185),
+ Variant::i32(2),
+ Variant::i64(2188),
+ Variant::i32(3),
+ Variant::i64(860),
+ Variant::i32(4),
+ Variant::i64(1527),
+ Variant::i32(5),
+ Variant::i64(2180),
+ ]),
+ ]
+ }
+
+ fn get_runtime() -> BufferSyncer {
+ BufferSyncer {
+ activities: map! {
+ 1 => MessageType::None,
+ 2 => MessageType::None,
+ 3 => MessageType::None,
+ 4 => MessageType::None,
+ 5 => MessageType::None,
+ },
+ highlight_counts: map! {
+ 1 => 0,
+ 2 => 0,
+ 3 => 0,
+ 4 => 0,
+ 5 => 0,
+ },
+ last_seen_msg: map! {
+ 1 => 2185,
+ 2 => 2188,
+ 3 => 860,
+ 4 => 2183,
+ 5 => 2180,
+ },
+ marker_line: map! {
+ 1 => 2185,
+ 2 => 2188,
+ 3 => 860,
+ 4 => 1527,
+ 5 => 2180,
+ },
+ }
+ }
+
+ // Disabled cus not sorted
+ // #[test]
+ // fn buffersyncer_to_network() {
+ // assert_eq!(get_runtime().to_network(), get_network())
+ // }
+
+ #[test]
+ fn buffersyncer_from_network() {
+ assert_eq!(
+ BufferSyncer::from_network(&mut get_network()),
+ get_runtime()
+ )
+ }
+}
diff --git a/src/message/signalproxy/objects/coreinfo.rs b/src/message/signalproxy/objects/coreinfo.rs
new file mode 100644
index 0000000..a717366
--- /dev/null
+++ b/src/message/signalproxy/objects/coreinfo.rs
@@ -0,0 +1,60 @@
+use libquassel_derive::Network;
+
+use crate::primitive::{DateTime, StringList};
+
+#[derive(Debug, Clone, PartialEq, Network)]
+#[network(repr = "map")]
+pub struct CoreInfo {
+ #[network(rename = "coreData", network, variant = "VariantMap")]
+ core_data: CoreData,
+}
+
+// // S->C calls
+// setCoreData(coreData: QVariantMap)
+// /**
+// * Replaces all properties of the object with the content of the
+// * "properties" parameter. This parameter is in network representation.
+// */
+// update(properties: QVariantMap)
+
+#[derive(Debug, Clone, PartialEq, Network)]
+#[network(repr = "map")]
+pub struct CoreData {
+ #[network(rename = "quasselVersion")]
+ quassel_version: String,
+ #[network(rename = "quasselBuildDate")]
+ quassel_build_date: String,
+ #[network(rename = "startTime")]
+ start_time: DateTime,
+ #[network(rename = "sessionConnectedClients")]
+ session_connected_clients: i32,
+ #[network(
+ rename = "sessionConnectedClientData",
+ variant = "VariantList",
+ network
+ )]
+ session_connected_client_data: Vec<ConnectedClient>,
+}
+
+#[derive(Debug, Clone, PartialEq, Network)]
+#[network(repr = "map")]
+pub struct ConnectedClient {
+ #[network(rename = "id")]
+ id: i32,
+ #[network(rename = "remoteAddress")]
+ remote_address: String,
+ #[network(rename = "location")]
+ location: String,
+ #[network(rename = "clientVersion")]
+ client_version: String,
+ #[network(rename = "clientVersionDate")]
+ client_version_date: String,
+ #[network(rename = "connectedSince")]
+ connected_since: DateTime,
+ #[network(rename = "secure")]
+ secure: bool,
+ #[network(rename = "features")]
+ features: i32,
+ #[network(rename = "featureList")]
+ feature_list: StringList,
+}
diff --git a/src/message/signalproxy/objects/highlightrulemanager.rs b/src/message/signalproxy/objects/highlightrulemanager.rs
new file mode 100644
index 0000000..d579254
--- /dev/null
+++ b/src/message/signalproxy/objects/highlightrulemanager.rs
@@ -0,0 +1,113 @@
+use libquassel_derive::Network;
+
+use num_derive::{FromPrimitive, ToPrimitive};
+use num_traits::{FromPrimitive, ToPrimitive};
+
+#[derive(Debug, Clone, PartialEq, Network)]
+#[network(repr = "list")]
+pub struct HighlightRuleManager {
+ #[network(rename = "highlightRuleList", network, variant = "VariantMap")]
+ highlight_rule_list: Vec<HighlightRule>,
+ #[network(rename = "highlightNick", network, variant = "i32")]
+ highlight_nick: HighlightNickType,
+ #[network(rename = "nicksCaseSensitive")]
+ nicks_case_sensitive: bool,
+}
+
+#[derive(Debug, Clone, PartialEq, Network)]
+#[network(repr = "maplist")]
+pub struct HighlightRule {
+ id: i32,
+ #[network(variant = "StringList")]
+ name: String,
+ #[network(rename = "isRegEx")]
+ is_regex: bool,
+ #[network(rename = "isCaseSensitive")]
+ is_case_sensitive: bool,
+ #[network(rename = "isEnabled")]
+ is_enabled: bool,
+ #[network(rename = "isInverse")]
+ is_inverse: bool,
+ #[network(variant = "StringList")]
+ sender: String,
+ #[network(variant = "StringList")]
+ channel: String,
+}
+
+#[derive(Debug, Clone, PartialEq, FromPrimitive, ToPrimitive)]
+pub enum HighlightNickType {
+ NoNick = 0x00,
+ CurrentNick = 0x01,
+ AllNicks = 0x02,
+}
+
+impl crate::message::signalproxy::Network for HighlightNickType {
+ type Item = i32;
+
+ fn to_network(&self) -> Self::Item {
+ self.to_i32().unwrap()
+ }
+
+ fn from_network(input: &mut Self::Item) -> Self {
+ Self::from_i32(*input).unwrap()
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use crate::message::signalproxy::translation::Network;
+ use crate::primitive::{Variant, VariantList};
+
+ use pretty_assertions::assert_eq;
+
+ fn get_network() -> VariantList {
+ vec![
+ Variant::ByteArray(s!("highlightRuleList")),
+ Variant::VariantMap(map! {
+ s!("isInverse") => Variant::VariantList(vec![Variant::bool(false)]),
+ s!("isEnabled") => Variant::VariantList(vec![Variant::bool(true)]),
+ s!("channel") => Variant::StringList(vec![s!("#test")]),
+ s!("sender") => Variant::StringList(vec![s!("testuser")]),
+ s!("isCaseSensitive") => Variant::VariantList(vec![Variant::bool(false)]),
+ s!("isRegEx") => Variant::VariantList(vec![Variant::bool(false)]),
+ s!("name") => Variant::StringList(vec![s!("testrule")]),
+ s!("id") => Variant::VariantList(vec![Variant::i32(1)]),
+ }),
+ Variant::ByteArray(s!("highlightNick")),
+ Variant::i32(1),
+ Variant::ByteArray(s!("nicksCaseSensitive")),
+ Variant::bool(false),
+ ]
+ }
+
+ fn get_runtime() -> HighlightRuleManager {
+ HighlightRuleManager {
+ highlight_rule_list: vec![HighlightRule {
+ id: 1,
+ name: s!("testrule"),
+ is_regex: false,
+ is_case_sensitive: false,
+ is_enabled: true,
+ is_inverse: false,
+ sender: s!("testuser"),
+ channel: s!("#test"),
+ }],
+ highlight_nick: HighlightNickType::CurrentNick,
+ nicks_case_sensitive: false,
+ }
+ }
+
+ #[test]
+ fn highlightrulemanager_to_network() {
+ assert_eq!(get_runtime().to_network(), get_network())
+ }
+
+ #[test]
+ fn highlightrulemanager_from_network() {
+ assert_eq!(
+ HighlightRuleManager::from_network(&mut get_network()),
+ get_runtime()
+ )
+ }
+}
diff --git a/src/message/signalproxy/objects/identity.rs b/src/message/signalproxy/objects/identity.rs
index a710e5d..744e777 100644
--- a/src/message/signalproxy/objects/identity.rs
+++ b/src/message/signalproxy/objects/identity.rs
@@ -1,119 +1,44 @@
-use crate::primitive::{Variant, VariantMap};
+use libquassel_derive::Network;
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, PartialEq, Network)]
+#[network(repr = "map")]
pub struct Identity {
+ #[network(rename = "identityId")]
identity_id: i32,
+ #[network(rename = "identityName")]
identity_name: String,
+ #[network(rename = "realName")]
real_name: String,
+ #[network(rename = "nicks", override_type = "StringList")]
nicks: Vec<String>,
+ #[network(rename = "awayNick")]
away_nick: String,
+ #[network(rename = "awayNickEnabled")]
away_nick_enabled: bool,
+ #[network(rename = "awayReason")]
away_reason: String,
+ #[network(rename = "awayReasonEnabled")]
away_reason_enabled: bool,
+ #[network(rename = "autoAwayEnabled")]
auto_away_enabled: bool,
+ #[network(rename = "autoAwayTime")]
auto_away_time: i32,
+ #[network(rename = "autoAwayReason")]
auto_away_reason: String,
+ #[network(rename = "autoAwayReasonEnabled")]
auto_away_reason_enabled: bool,
+ #[network(rename = "detachAwayEnabled")]
detach_away_enabled: bool,
+ #[network(rename = "detachAwayReason")]
detach_away_reason: String,
+ #[network(rename = "detachAwayReasonEnabled")]
detach_away_reason_enabled: bool,
+ #[network(rename = "ident")]
ident: String,
+ #[network(rename = "kickReason")]
kick_reason: String,
+ #[network(rename = "partReason")]
part_reason: String,
+ #[network(rename = "quitReason")]
quit_reason: String,
}
-
-impl From<VariantMap> for Identity {
- fn from(input: VariantMap) -> Self {
- Identity {
- identity_id: match_variant!(input.get("identityId").unwrap(), Variant::i32),
- identity_name: match_variant!(input.get("identityName").unwrap(), Variant::String),
- real_name: match_variant!(input.get("realName").unwrap(), Variant::String),
- nicks: match_variant!(input.get("nicks").unwrap(), Variant::StringList),
- away_nick: match_variant!(input.get("awayNick").unwrap(), Variant::String),
- away_nick_enabled: match_variant!(input.get("awayNickEnabled").unwrap(), Variant::bool),
- away_reason: match_variant!(input.get("awayReason").unwrap(), Variant::String),
- away_reason_enabled: match_variant!(
- input.get("awayReasonEnabled").unwrap(),
- Variant::bool
- ),
- auto_away_enabled: match_variant!(input.get("autoAwayEnabled").unwrap(), Variant::bool),
- auto_away_time: match_variant!(input.get("autoAwayTime").unwrap(), Variant::i32),
- auto_away_reason: match_variant!(input.get("autoAwayReason").unwrap(), Variant::String),
- auto_away_reason_enabled: match_variant!(
- input.get("autoAwayReasonEnabled").unwrap(),
- Variant::bool
- ),
- detach_away_enabled: match_variant!(
- input.get("detachAwayEnabled").unwrap(),
- Variant::bool
- ),
- detach_away_reason: match_variant!(
- input.get("detachAwayReason").unwrap(),
- Variant::String
- ),
- detach_away_reason_enabled: match_variant!(
- input.get("detachAwayReasonEnabled").unwrap(),
- Variant::bool
- ),
- ident: match_variant!(input.get("ident").unwrap(), Variant::String),
- kick_reason: match_variant!(input.get("kickReason").unwrap(), Variant::String),
- part_reason: match_variant!(input.get("partReason").unwrap(), Variant::String),
- quit_reason: match_variant!(input.get("quitReason").unwrap(), Variant::String),
- }
- }
-}
-
-impl Into<std::collections::HashMap<String, Variant>> for Identity {
- fn into(self) -> VariantMap {
- let mut res = VariantMap::with_capacity(19);
-
- res.insert("identityId".to_string(), Variant::i32(self.identity_id));
- res.insert(
- "identityName".to_string(),
- Variant::String(self.identity_name),
- );
- res.insert("realName".to_string(), Variant::String(self.real_name));
- res.insert("nicks".to_string(), Variant::StringList(self.nicks));
- res.insert("awayNick".to_string(), Variant::String(self.away_nick));
- res.insert(
- "awayNickEnabled".to_string(),
- Variant::bool(self.away_nick_enabled),
- );
- res.insert("awayReason".to_string(), Variant::String(self.away_reason));
- res.insert(
- "awayReasonEnabled".to_string(),
- Variant::bool(self.away_reason_enabled),
- );
- res.insert(
- "autoAwayEnabled".to_string(),
- Variant::bool(self.auto_away_enabled),
- );
- res.insert(
- "autoAwayTime".to_string(),
- Variant::i32(self.auto_away_time),
- );
- res.insert(
- "autoAwayReason".to_string(),
- Variant::String(self.auto_away_reason),
- );
- res.insert(
- "detachAwayEnabled".to_string(),
- Variant::bool(self.detach_away_enabled),
- );
- res.insert(
- "detachAwayReason".to_string(),
- Variant::String(self.detach_away_reason),
- );
- res.insert(
- "detachAwayReasonEnabled".to_string(),
- Variant::bool(self.detach_away_reason_enabled),
- );
- res.insert("ident".to_string(), Variant::String(self.ident));
- res.insert("kickReason".to_string(), Variant::String(self.kick_reason));
- res.insert("partReason".to_string(), Variant::String(self.part_reason));
- res.insert("quitReason".to_string(), Variant::String(self.quit_reason));
-
- res
- }
-}
diff --git a/src/message/signalproxy/objects/ircchannel.rs b/src/message/signalproxy/objects/ircchannel.rs
index b15d789..ee23f07 100644
--- a/src/message/signalproxy/objects/ircchannel.rs
+++ b/src/message/signalproxy/objects/ircchannel.rs
@@ -1,22 +1,119 @@
use std::collections::HashMap;
+use std::convert::TryFrom;
+use std::convert::TryInto;
-use crate::primitive::{StringList, Variant, VariantMap};
+use crate::primitive::{StringList, Variant, VariantList, VariantMap};
-#[allow(unused_imports)]
use crate::message::signalproxy::Network;
#[allow(dead_code)]
#[derive(Debug, Clone, PartialEq)]
pub struct IrcChannel {
- channel_modes_a: HashMap<char, StringList>,
- channel_modes_b: HashMap<char, String>,
- channel_modes_c: HashMap<char, String>,
- channel_modes_d: String,
- user_modes: HashMap<String, String>,
- name: String,
- topic: String,
- password: String,
- encrypted: bool,
+ pub channel_modes_a: HashMap<char, StringList>,
+ pub channel_modes_b: HashMap<char, String>,
+ pub channel_modes_c: HashMap<char, String>,
+ pub channel_modes_d: String,
+ // pub channel_modes: HashMap<char, ChannelMode>,
+ pub user_modes: HashMap<String, String>,
+ pub name: String,
+ pub topic: String,
+ pub password: String,
+ pub encrypted: bool,
+}
+
+// #[derive(Debug, Clone, PartialEq)]
+// pub enum ChannelMode {
+// A(char, StringList),
+// B(char, String),
+// C(char, String),
+// D(char),
+// }
+
+impl Network for Vec<IrcChannel> {
+ type Item = VariantMap;
+
+ fn to_network(&self) -> Self::Item {
+ let mut channelmodes: VariantList = Vec::with_capacity(self.len());
+ let mut usermodes: VariantList = Vec::with_capacity(self.len());
+ let mut name: VariantList = Vec::with_capacity(self.len());
+ let mut topic: VariantList = Vec::with_capacity(self.len());
+ let mut password: VariantList = Vec::with_capacity(self.len());
+ let mut encrypted: VariantList = Vec::with_capacity(self.len());
+
+ let mut map = VariantMap::new();
+
+ self.iter().for_each(|item| {
+ channelmodes.push(Variant::VariantMap({
+ let mut map = VariantMap::new();
+
+ map.insert(
+ s!("A"),
+ Variant::VariantMap(
+ item.channel_modes_a
+ .iter()
+ .map(|(k, v)| (k.to_string(), Variant::StringList(v.clone())))
+ .collect(),
+ ),
+ );
+ map.insert(
+ s!("B"),
+ Variant::VariantMap(
+ item.channel_modes_b
+ .iter()
+ .map(|(k, v)| (k.to_string(), Variant::String(v.clone())))
+ .collect(),
+ ),
+ );
+ map.insert(
+ s!("C"),
+ Variant::VariantMap(
+ item.channel_modes_c
+ .iter()
+ .map(|(k, v)| (k.to_string(), Variant::String(v.clone())))
+ .collect(),
+ ),
+ );
+ map.insert(s!("D"), Variant::String(item.channel_modes_d.clone()));
+
+ map
+ }));
+
+ usermodes.push(Variant::VariantMap(
+ item.user_modes
+ .iter()
+ .map(|(k, v)| (k.clone(), Variant::String(v.clone())))
+ .collect(),
+ ));
+ name.push(Variant::String(item.name.clone()));
+ topic.push(Variant::String(item.topic.clone()));
+ password.push(Variant::String(item.password.clone()));
+ encrypted.push(Variant::bool(item.encrypted));
+ });
+
+ map.insert(
+ String::from("ChanModes"),
+ Variant::VariantList(channelmodes),
+ );
+ map.insert(String::from("UserModes"), Variant::VariantList(usermodes));
+ map.insert(String::from("name"), Variant::VariantList(name));
+ map.insert(String::from("topic"), Variant::VariantList(topic));
+ map.insert(String::from("password"), Variant::VariantList(password));
+ map.insert(String::from("encrypted"), Variant::VariantList(encrypted));
+
+ map
+ }
+
+ fn from_network(input: &mut Self::Item) -> Self {
+ let marker: VariantList =
+ std::convert::TryInto::try_into(input.get("name").unwrap()).unwrap();
+
+ let mut res = Vec::new();
+ for _ in 0..marker.len() {
+ res.push(IrcChannel::from_network(input));
+ }
+
+ return res;
+ }
}
impl Network for IrcChannel {
@@ -92,90 +189,48 @@ impl Network for IrcChannel {
res
}
fn from_network(input: &mut Self::Item) -> Self {
+ let mut chanmodes: VariantMap = match_variant!(
+ match_variant!(input.get_mut("ChanModes").unwrap(), Variant::VariantList).remove(0),
+ Variant::VariantMap
+ );
+
Self {
- channel_modes_a: match_variant!(
- match_variant!(
- match_variant!(input.get("ChanModes").unwrap(), Variant::VariantList)[0],
- Variant::VariantMap
- )
- .get("B")
- .unwrap(),
- Variant::VariantMap
+ channel_modes_a: match_variant!(chanmodes.remove("A").unwrap(), Variant::VariantMap)
+ .into_iter()
+ .map(|(mut k, v)| (k.remove(0), match_variant!(v, Variant::StringList)))
+ .collect(),
+ channel_modes_b: match_variant!(chanmodes.remove("B").unwrap(), Variant::VariantMap)
+ .into_iter()
+ .map(|(mut k, v)| (k.remove(0), match_variant!(v, Variant::String)))
+ .collect(),
+ channel_modes_c: match_variant!(chanmodes.remove("C").unwrap(), Variant::VariantMap)
+ .into_iter()
+ .map(|(mut k, v)| (k.remove(0), match_variant!(v, Variant::String)))
+ .collect(),
+ channel_modes_d: match_variant!(chanmodes.remove("D").unwrap(), Variant::String),
+ user_modes: VariantMap::try_from(
+ match_variant!(input.get_mut("UserModes").unwrap(), Variant::VariantList).remove(0),
)
- .iter()
- .map(|(k, v)| {
- (
- k.chars().nth(0).unwrap(),
- match_variant!(v, Variant::StringList),
- )
- })
+ .unwrap()
+ .into_iter()
+ .map(|(k, v)| (k, v.try_into().unwrap()))
.collect(),
- channel_modes_b: match_variant!(
- match_variant!(
- match_variant!(input.get("ChanModes").unwrap(), Variant::VariantList)[0],
- Variant::VariantMap
- )
- .get("B")
+ name: match_variant!(input.get_mut("name").unwrap(), Variant::VariantList)
+ .remove(0)
+ .try_into()
.unwrap(),
- Variant::VariantMap
- )
- .iter()
- .map(|(k, v)| {
- (
- k.chars().nth(0).unwrap(),
- match_variant!(v, Variant::String),
- )
- })
- .collect(),
- channel_modes_c: match_variant!(
- match_variant!(
- match_variant!(input.get("ChanModes").unwrap(), Variant::VariantList)[0],
- Variant::VariantMap
- )
- .get("C")
+ topic: match_variant!(input.get_mut("topic").unwrap(), Variant::VariantList)
+ .remove(0)
+ .try_into()
.unwrap(),
- Variant::VariantMap
- )
- .iter()
- .map(|(k, v)| {
- (
- k.chars().nth(0).unwrap(),
- match_variant!(v, Variant::String),
- )
- })
- .collect(),
- channel_modes_d: match_variant!(
- match_variant!(
- match_variant!(input.get("ChanModes").unwrap(), Variant::VariantList)[0],
- Variant::VariantMap
- )
- .get("D")
+ password: match_variant!(input.get_mut("password").unwrap(), Variant::VariantList)
+ .remove(0)
+ .try_into()
+ .unwrap(),
+ encrypted: match_variant!(input.get_mut("encrypted").unwrap(), Variant::VariantList)
+ .remove(0)
+ .try_into()
.unwrap(),
- Variant::String
- ),
- user_modes: match_variant!(
- match_variant!(input.get("UserModes").unwrap(), Variant::VariantList)[0],
- Variant::VariantMap
- )
- .iter()
- .map(|(k, v)| (k.clone(), match_variant!(v, Variant::String)))
- .collect(),
- name: match_variant!(
- match_variant!(input.get("name").unwrap(), Variant::VariantList)[0],
- Variant::String
- ),
- topic: match_variant!(
- match_variant!(input.get("topic").unwrap(), Variant::VariantList)[0],
- Variant::String
- ),
- password: match_variant!(
- match_variant!(input.get("password").unwrap(), Variant::VariantList)[0],
- Variant::String
- ),
- encrypted: match_variant!(
- match_variant!(input.get("encrypted").unwrap(), Variant::VariantList)[0],
- Variant::bool
- ),
}
}
}
@@ -185,7 +240,7 @@ mod tests {
use super::*;
fn get_network() -> VariantMap {
- VariantMap::from(map! {
+ map! {
s!("encrypted") => Variant::VariantList(
vec![
Variant::bool(
@@ -233,9 +288,9 @@ mod tests {
),
},
),
- s!("A") => Variant::VariantMap(map!
- {},
- ),
+ s!("A") => Variant::VariantMap(map! {
+ s!("b") => Variant::StringList(vec![s!("*!*@test"), s!("*!*@test2")]),
+ }),
},
),
],
@@ -261,11 +316,11 @@ mod tests {
),
],
)
- })
+ }
}
fn get_runtime() -> IrcChannel {
IrcChannel {
- channel_modes_a: map! {},
+ channel_modes_a: map! { 'b' => vec![s!("*!*@test"), s!("*!*@test2")] },
channel_modes_b: map! {},
channel_modes_c: map! { 'j' => s!("5:1"), 'x' => s!("10:5"), 'f' => s!("30:5"), 'F' => s!("5:60") },
channel_modes_d: s!("tCnT"),
diff --git a/src/message/signalproxy/objects/ircuser.rs b/src/message/signalproxy/objects/ircuser.rs
index 1064965..85fea81 100644
--- a/src/message/signalproxy/objects/ircuser.rs
+++ b/src/message/signalproxy/objects/ircuser.rs
@@ -1,56 +1,39 @@
-use std::collections::HashMap;
-
-use crate::primitive::{DateTime, StringList, Variant, VariantMap};
+use crate::primitive::{DateTime, StringList};
#[allow(unused_imports)]
use crate::message::signalproxy::Network;
use libquassel_derive::Network;
-impl Network for Vec<IrcUser> {
- type Item = VariantMap;
-
- fn to_network(&self) -> Self::Item {
- Variant::VariantMap(self.iter().fold(HashMap::new(), |mut res, v| {
- res.extend(v.to_network());
-
- res
- }))
- }
- fn from_network(input: &mut Self::Item) -> Self {
- todo!()
- }
-}
-
#[allow(dead_code)]
#[derive(Debug, Clone, PartialEq, Network)]
#[network(repr = "maplist")]
pub struct IrcUser {
- user: String,
- host: String,
- nick: String,
+ pub user: String,
+ pub host: String,
+ pub nick: String,
#[network(rename = "realName")]
- real_name: String,
- account: String,
- away: bool,
+ pub real_name: String,
+ pub account: String,
+ pub away: bool,
#[network(rename = "awayMessage")]
- away_message: String,
+ pub away_message: String,
#[network(rename = "idleTime")]
- idle_time: DateTime,
+ pub idle_time: DateTime,
#[network(rename = "loginTime")]
- login_time: DateTime,
- server: String,
+ pub login_time: DateTime,
+ pub server: String,
#[network(rename = "ircOperator")]
- irc_operator: String,
+ pub irc_operator: String,
#[network(rename = "lastAwayMessageTime")]
- last_away_message_time: DateTime,
+ pub last_away_message_time: DateTime,
#[network(rename = "whoisServiceReply")]
- whois_service_reply: String,
+ pub whois_service_reply: String,
#[network(rename = "suserHost")]
- suser_host: String,
- encrypted: bool,
- channels: StringList,
+ pub suser_host: String,
+ pub encrypted: bool,
+ pub channels: StringList,
#[network(rename = "userModes")]
- user_modes: String,
+ pub user_modes: String,
}
#[cfg(test)]
diff --git a/src/message/signalproxy/objects/mod.rs b/src/message/signalproxy/objects/mod.rs
index 84f2f5a..2fc4745 100644
--- a/src/message/signalproxy/objects/mod.rs
+++ b/src/message/signalproxy/objects/mod.rs
@@ -1,15 +1,62 @@
mod aliasmanager;
mod buffersyncer;
+mod coreinfo;
+mod highlightrulemanager;
mod identity;
-// mod ircchannel;
-// mod ircuser;
-// mod network;
-// mod networkinfo;
+mod ircchannel;
+mod ircuser;
+mod network;
+mod networkinfo;
+
+use std::convert::TryInto;
pub use aliasmanager::*;
pub use buffersyncer::*;
+pub use coreinfo::*;
+pub use highlightrulemanager::*;
pub use identity::*;
+pub use ircchannel::*;
+pub use ircuser::*;
+pub use network::*;
+pub use networkinfo::*;
+
+use libquassel_derive::From;
+
+use super::Network;
+use crate::primitive::VariantList;
+
+#[derive(Debug, Clone, PartialEq, From)]
+pub enum Types {
+ AliasManager(AliasManager),
+ Network(network::Network),
+ NetworkInfo(NetworkInfo),
+ NetworkConfig(NetworkConfig),
+ CoreData(CoreData),
+ Unknown(VariantList),
+}
+
+impl Types {
+ pub fn to_network(&self) -> VariantList {
+ match self {
+ Types::AliasManager(val) => val.to_network(),
+ Types::Network(val) => val.to_network(),
+ Types::NetworkInfo(val) => val.to_network(),
+ Types::NetworkConfig(val) => val.to_network(),
+ Types::CoreData(val) => vec![val.to_network().into()],
+ Types::Unknown(val) => val.clone(),
+ }
+ }
-pub trait Act {
- fn act(self: Self);
+ pub fn from_network(class_name: &str, input: &mut VariantList) -> Self {
+ match class_name {
+ "Network" => Types::Network(Network::from_network(input)),
+ "NetworkInfo" => Types::NetworkInfo(NetworkInfo::from_network(input)),
+ "NetworkConfig" => Types::NetworkConfig(NetworkConfig::from_network(input)),
+ "AliasManager" => Types::AliasManager(AliasManager::from_network(input)),
+ "CoreData" => Types::CoreData(CoreData::from_network(
+ &mut input.remove(0).try_into().unwrap(),
+ )),
+ _ => Types::Unknown(input.to_owned()),
+ }
+ }
}
diff --git a/src/message/signalproxy/objects/network.rs b/src/message/signalproxy/objects/network.rs
index 4075499..6bf9265 100644
--- a/src/message/signalproxy/objects/network.rs
+++ b/src/message/signalproxy/objects/network.rs
@@ -1,16 +1,17 @@
-use crate::primitive::{StringList, Variant, VariantList, VariantMap};
+use std::convert::TryInto;
+
+use crate::primitive::{Variant, VariantList, VariantMap};
-#[allow(unused_imports)]
use libquassel_derive::Network;
use std::collections::HashMap;
use num_derive::{FromPrimitive, ToPrimitive};
-use num_traits::{FromPrimitive, ToPrimitive};
+use num_traits::FromPrimitive;
use super::{ircchannel::IrcChannel, ircuser::IrcUser, networkinfo::NetworkInfo};
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, PartialEq)]
pub struct Network {
my_nick: String,
latency: i32,
@@ -105,146 +106,104 @@ impl crate::message::signalproxy::Network for Network {
}
fn from_network(input: &mut Self::Item) -> Self {
- let users_and_channels = match_variant!(
- input
- .iter()
- .nth(
- input
- .iter()
- .position(|x| *x == Variant::ByteArray(s!("IrcUsersAndChannels")))
- .unwrap()
- )
- .unwrap(),
- Variant::VariantMap
- );
-
- let res = Self {
- my_nick: match_variant!(
- input
- .iter()
- .nth(
- input
- .iter()
- .position(|x| *x == Variant::ByteArray(s!("myNick")))
- .unwrap()
- )
- .unwrap(),
- Variant::String
- ),
- latency: match_variant!(
- input
- .iter()
- .nth(
- input
- .iter()
- .position(|x| *x == Variant::ByteArray(s!("latency")))
- .unwrap()
- )
- .unwrap(),
- Variant::i32
- ),
- current_server: match_variant!(
- input
- .iter()
- .nth(
- input
- .iter()
- .position(|x| *x == Variant::ByteArray(s!("currentServer")))
- .unwrap()
- )
- .unwrap(),
- Variant::String
- ),
- is_connected: match_variant!(
- input
- .iter()
- .nth(
- input
- .iter()
- .position(|x| *x == Variant::ByteArray(s!("isConnected")))
- .unwrap()
- )
- .unwrap(),
- Variant::bool
- ),
- connection_state: ConnectionState::from_i32(match_variant!(
- input
- .iter()
- .nth(
- input
- .iter()
- .position(|x| *x == Variant::ByteArray(s!("connectionState")))
- .unwrap()
- )
- .unwrap(),
- Variant::i32
- ))
- .unwrap(),
- irc_users: match_variant!(
- users_and_channels.get("Users").unwrap(),
- Variant::VariantMap
- )
- .iter()
- .map(|(k, v)| (k, IrcUser::from_network(v))),
- irc_channels: match_variant!(
- users_and_channels.get("Channels").unwrap(),
- Variant::VariantMap
- )
- .iter()
- .map(|(k, v)| (k, match_variant!(v, Variant::VariantList))),
- supports: match_variant!(
- input
- .iter()
- .nth(
- input
- .iter()
- .position(|x| *x == Variant::ByteArray(s!("Supports")))
- .unwrap()
- )
- .unwrap(),
- Variant::VariantMap
- )
- .iter()
- .map(|(k, v)| (k.clone(), match_variant!(v, Variant::String)))
- .collect(),
- caps: match_variant!(
- input
- .iter()
- .nth(
- input
- .iter()
- .position(|x| *x == Variant::ByteArray(s!("Caps")))
- .unwrap()
- )
- .unwrap(),
- Variant::VariantMap
- )
- .iter()
- .map(|(k, v)| (k.clone(), match_variant!(v, Variant::String)))
- .collect(),
- caps_enabled: match_variant!(
- input
- .iter()
- .nth(
- input
- .iter()
- .position(|x| *x == Variant::ByteArray(s!("CapsEnabled")))
- .unwrap()
- )
- .unwrap(),
- Variant::VariantList
- )
- .iter()
- .map(|v| match_variant!(v, Variant::String))
- .collect(),
- network_info: NetworkInfo::from_network(input),
+ let mut i = input.iter().cycle();
+
+ let users_and_channels: VariantMap = {
+ i.position(|x| *x == Variant::ByteArray(String::from("IrcUsersAndChannels")))
+ .unwrap();
+
+ i.next().unwrap().try_into().unwrap()
};
- todo!()
+ log::trace!("users and channels: {:#?}", users_and_channels);
+
+ Self {
+ my_nick: {
+ i.position(|x| *x == Variant::ByteArray(String::from("myNick")))
+ .unwrap();
+
+ i.next().unwrap().try_into().unwrap()
+ },
+ latency: {
+ i.position(|x| *x == Variant::ByteArray(String::from("latency")))
+ .unwrap();
+
+ i.next().unwrap().try_into().unwrap()
+ },
+ current_server: {
+ i.position(|x| *x == Variant::ByteArray(String::from("currentServer")))
+ .unwrap();
+
+ i.next().unwrap().try_into().unwrap()
+ },
+ is_connected: {
+ i.position(|x| *x == Variant::ByteArray(String::from("isConnected")))
+ .unwrap();
+
+ i.next().unwrap().try_into().unwrap()
+ },
+ connection_state: ConnectionState::from_i32({
+ i.position(|x| *x == Variant::ByteArray(String::from("connectionState")))
+ .unwrap();
+
+ i.next().unwrap().try_into().unwrap()
+ })
+ .unwrap(),
+ irc_users: {
+ let users: Vec<IrcUser> = Vec::<IrcUser>::from_network(
+ &mut users_and_channels.get("Users").unwrap().try_into().unwrap(),
+ );
+ users
+ .into_iter()
+ .map(|user| (user.nick.clone(), user))
+ .collect()
+ },
+ irc_channels: {
+ let channels: Vec<IrcChannel> = Vec::<IrcChannel>::from_network(
+ &mut users_and_channels
+ .get("Channels")
+ .unwrap()
+ .try_into()
+ .unwrap(),
+ );
+ channels
+ .into_iter()
+ .map(|channel| (channel.name.clone(), channel))
+ .collect()
+ },
+ supports: {
+ i.position(|x| *x == Variant::ByteArray(String::from("Supports")))
+ .unwrap();
+
+ let var: VariantMap = i.next().unwrap().try_into().unwrap();
+
+ var.into_iter()
+ .map(|(k, v)| (k, v.try_into().unwrap()))
+ .collect()
+ },
+ caps: {
+ i.position(|x| *x == Variant::ByteArray(String::from("Caps")))
+ .unwrap();
+
+ let var: VariantMap = i.next().unwrap().try_into().unwrap();
+
+ var.into_iter()
+ .map(|(k, v)| (k, v.try_into().unwrap()))
+ .collect()
+ },
+ caps_enabled: {
+ i.position(|x| *x == Variant::ByteArray(String::from("CapsEnabled")))
+ .unwrap();
+
+ let var: VariantList = i.next().unwrap().try_into().unwrap();
+
+ var.into_iter().map(|v| v.try_into().unwrap()).collect()
+ },
+ network_info: NetworkInfo::from_network(input),
+ }
}
}
-#[allow(dead_code)]
#[derive(Debug, Clone, PartialEq, Network)]
#[network(repr = "map")]
pub struct NetworkServer {
@@ -274,6 +233,27 @@ pub struct NetworkServer {
pub proxy_pass: String,
}
+#[derive(Debug, Clone, PartialEq, Network)]
+#[network(repr = "list")]
+pub struct NetworkConfig {
+ #[network(rename = "pingTimeoutEnabled")]
+ ping_timeout_enabled: bool,
+ #[network(rename = "pingInterval")]
+ ping_interval: i32,
+ #[network(rename = "maxPingCount")]
+ max_ping_count: i32,
+ #[network(rename = "autoWhoEnabled")]
+ auto_who_enabled: bool,
+ #[network(rename = "autoWhoInterval")]
+ auto_who_interval: i32,
+ #[network(rename = "autoWhoNickLimit")]
+ auto_who_nick_limit: i32,
+ #[network(rename = "autoWhoDelay")]
+ auto_who_delay: i32,
+ #[network(rename = "standardCtcp")]
+ standard_ctcp: bool,
+}
+
#[cfg(test)]
mod tests {
use super::*;
diff --git a/src/message/signalproxy/objects/networkinfo.rs b/src/message/signalproxy/objects/networkinfo.rs
index e36297d..e5aa6ea 100644
--- a/src/message/signalproxy/objects/networkinfo.rs
+++ b/src/message/signalproxy/objects/networkinfo.rs
@@ -1,23 +1,16 @@
-use crate::primitive::{StringList, Variant};
+use crate::primitive::StringList;
-#[allow(unused_imports)]
use libquassel_derive::Network;
use crate::message::objects::network::NetworkServer;
-#[allow(dead_code)]
#[derive(Debug, Clone, PartialEq, Network)]
#[network(repr = "list")]
pub struct NetworkInfo {
#[network(rename = "networkName")]
pub network_name: String,
- #[network(
- rename = "ServerList",
- override_type = "VariantList",
- to_map = "|server| Variant::VariantMap(server.to_network())",
- from_map = "|server| NetworkServer::from_network(&mut match_variant!(server, Variant::VariantMap))"
- )]
+ #[network(rename = "ServerList", network, variant = "VariantList")]
pub server_list: Vec<NetworkServer>,
#[network(rename = "perform")]
pub perform: StringList,
@@ -75,15 +68,12 @@ pub struct NetworkInfo {
#[cfg(test)]
mod tests {
- use crate::{
- message::objects::network::NetworkServer,
- primitive::{Variant, VariantList},
- };
+ use crate::primitive::{Variant, VariantList};
use super::*;
use crate::message::signalproxy::translation::Network;
- use pretty_assertions::{assert_eq, assert_ne};
+ use pretty_assertions::assert_eq;
fn get_network() -> VariantList {
vec![
diff --git a/src/message/signalproxy/rpccall.rs b/src/message/signalproxy/rpccall.rs
index 2755ea1..0b5c598 100644
--- a/src/message/signalproxy/rpccall.rs
+++ b/src/message/signalproxy/rpccall.rs
@@ -1,7 +1,7 @@
use crate::message::MessageType;
use crate::primitive::Message;
use crate::primitive::{Variant, VariantList};
-use crate::{Deserialize, Serialize};
+use crate::{deserialize::Deserialize, serialize::Serialize};
#[derive(Clone, Debug, std::cmp::PartialEq)]
pub enum RpcCall {
diff --git a/src/message/signalproxy/syncmessage.rs b/src/message/signalproxy/syncmessage.rs
index b58659a..9c1716b 100644
--- a/src/message/signalproxy/syncmessage.rs
+++ b/src/message/signalproxy/syncmessage.rs
@@ -1,6 +1,6 @@
use crate::message::MessageType;
use crate::primitive::{Variant, VariantList};
-use crate::{Deserialize, Serialize};
+use crate::{deserialize::Deserialize, serialize::Serialize};
#[derive(Clone, Debug, std::cmp::PartialEq)]
pub struct SyncMessage {
diff --git a/src/primitive/bufferinfo.rs b/src/primitive/bufferinfo.rs
index 24080cb..97d9408 100644
--- a/src/primitive/bufferinfo.rs
+++ b/src/primitive/bufferinfo.rs
@@ -2,8 +2,7 @@ use std::vec::Vec;
use failure::Error;
-use crate::{Deserialize, DeserializeUTF8};
-use crate::{Serialize, SerializeUTF8};
+use crate::{deserialize::*, serialize::*};
/// The BufferInfo struct represents a BufferInfo as received in IRC
///
diff --git a/src/primitive/datetime.rs b/src/primitive/datetime.rs
index e4c4c83..8d78b32 100644
--- a/src/primitive/datetime.rs
+++ b/src/primitive/datetime.rs
@@ -1,5 +1,4 @@
-use crate::Deserialize;
-use crate::Serialize;
+use crate::{deserialize::*, serialize::*};
use time::{OffsetDateTime, PrimitiveDateTime, UtcOffset};
diff --git a/src/primitive/message.rs b/src/primitive/message.rs
index 04c427e..36a55c5 100644
--- a/src/primitive/message.rs
+++ b/src/primitive/message.rs
@@ -1,9 +1,10 @@
use std::vec::Vec;
+use num_derive::{FromPrimitive, ToPrimitive};
+
use failure::Error;
-use crate::{Deserialize, DeserializeUTF8};
-use crate::{Serialize, SerializeUTF8};
+use crate::{deserialize::*, serialize::*};
use crate::primitive::BufferInfo;
@@ -171,8 +172,9 @@ impl Deserialize for Message {
}
#[repr(i32)]
-#[derive(Copy, Clone, Debug, std::cmp::PartialEq)]
+#[derive(Copy, Clone, Debug, std::cmp::PartialEq, FromPrimitive, ToPrimitive)]
pub enum MessageType {
+ None = 0x00000000,
Plain = 0x00000001,
Notice = 0x00000002,
Action = 0x00000004,
diff --git a/src/primitive/signedint.rs b/src/primitive/signedint.rs
index a1254fb..2d2029d 100644
--- a/src/primitive/signedint.rs
+++ b/src/primitive/signedint.rs
@@ -6,7 +6,7 @@ use std::vec::Vec;
use failure::Error;
-use crate::{Deserialize, Serialize};
+use crate::{deserialize::*, serialize::*};
impl Serialize for i64 {
fn serialize(&self) -> Result<Vec<u8>, Error> {
diff --git a/src/primitive/string.rs b/src/primitive/string.rs
index 7ea838d..478bc0a 100644
--- a/src/primitive/string.rs
+++ b/src/primitive/string.rs
@@ -8,9 +8,7 @@ use failure::Error;
use log::trace;
use crate::util;
-use crate::{Deserialize, DeserializeUTF8, Serialize, SerializeUTF8};
-
-pub type ByteArray = String;
+use crate::{deserialize::*, serialize::*};
/// We Shadow the String type here as we can only use impl on types in our own scope.
///
@@ -21,10 +19,8 @@ impl Serialize for String {
fn serialize(&self) -> Result<Vec<u8>, Error> {
let mut res: Vec<u8> = Vec::new();
- let utf16: Vec<u16> = self.encode_utf16().collect();
- for i in utf16 {
- res.extend(i.to_be_bytes().iter());
- }
+ self.encode_utf16()
+ .for_each(|i| res.extend(i.to_be_bytes().iter()));
util::prepend_byte_len(&mut res);
return Ok(res);
diff --git a/src/primitive/stringlist.rs b/src/primitive/stringlist.rs
index df6d281..ceea63e 100644
--- a/src/primitive/stringlist.rs
+++ b/src/primitive/stringlist.rs
@@ -8,7 +8,7 @@ use failure::Error;
use log::trace;
-use crate::{Deserialize, Serialize};
+use crate::{deserialize::*, serialize::*};
/// StringList are represented as a Vec of Strings
///
diff --git a/src/primitive/unsignedint.rs b/src/primitive/unsignedint.rs
index 6e91e2a..90ec696 100644
--- a/src/primitive/unsignedint.rs
+++ b/src/primitive/unsignedint.rs
@@ -8,7 +8,7 @@ use std::vec::Vec;
use failure::Error;
use crate::error::ProtocolError;
-use crate::{Deserialize, Serialize};
+use crate::{deserialize::*, serialize::*};
impl Serialize for bool {
fn serialize(&self) -> Result<Vec<u8>, Error> {
diff --git a/src/primitive/variant.rs b/src/primitive/variant.rs
index 8a98d59..efe69b8 100644
--- a/src/primitive/variant.rs
+++ b/src/primitive/variant.rs
@@ -7,8 +7,7 @@ use log::{error, trace};
use crate::error::ProtocolError;
use crate::primitive;
use crate::primitive::StringList;
-use crate::{Deserialize, DeserializeUTF8};
-use crate::{Serialize, SerializeUTF8};
+use crate::{deserialize::*, serialize::*};
use crate::primitive::{BufferInfo, Date, DateTime, Message, Time, VariantList, VariantMap};
@@ -35,6 +34,7 @@ pub enum Variant {
DateTime(DateTime),
VariantMap(VariantMap),
VariantList(VariantList),
+ #[from(ignore)]
String(String),
#[from(ignore)]
ByteArray(String),
@@ -50,6 +50,32 @@ pub enum Variant {
i8(i8),
}
+impl From<Variant> for String {
+ fn from(input: Variant) -> Self {
+ match input {
+ Variant::String(value) => value,
+ Variant::ByteArray(value) => value,
+ _ => panic!("unknown variant expected string or bytearray"),
+ }
+ }
+}
+
+impl From<&Variant> for String {
+ fn from(input: &Variant) -> Self {
+ match input {
+ Variant::String(value) => value.clone(),
+ Variant::ByteArray(value) => value.clone(),
+ _ => panic!("unknown variant expected string or bytearray"),
+ }
+ }
+}
+
+impl From<String> for Variant {
+ fn from(input: String) -> Self {
+ Self::String(input)
+ }
+}
+
impl Serialize for Variant {
fn serialize(&self) -> Result<Vec<u8>, Error> {
let unknown: u8 = 0x00;
diff --git a/src/primitive/variantlist.rs b/src/primitive/variantlist.rs
index 7e74122..2d20ae2 100644
--- a/src/primitive/variantlist.rs
+++ b/src/primitive/variantlist.rs
@@ -5,7 +5,7 @@ use failure::Error;
use log::trace;
-use crate::{Deserialize, Serialize};
+use crate::{deserialize::*, serialize::*};
use crate::primitive::Variant;
diff --git a/src/primitive/variantmap.rs b/src/primitive/variantmap.rs
index d43028c..8c1032d 100644
--- a/src/primitive/variantmap.rs
+++ b/src/primitive/variantmap.rs
@@ -5,8 +5,7 @@ use failure::Error;
use log::trace;
-use crate::Deserialize;
-use crate::Serialize;
+use crate::{deserialize::*, serialize::*};
use crate::primitive::Variant;
use crate::util;
@@ -40,11 +39,11 @@ impl Deserialize for VariantMap {
let mut pos: usize = 4;
let mut map = VariantMap::new();
for _ in 0..len {
- trace!(target: "primitive::VariantMap", "Parsing entry name");
+ trace!(target: "primitive::VariantMap", "Parsing entry name {:x?}", &b[pos..]);
let (nlen, name) = String::parse(&b[pos..])?;
pos += nlen;
- trace!(target: "primitive::VariantMap", "Parsing entry: {:?} with len {:?}", name, &b[(pos)..(pos + 4)]);
+ trace!(target: "primitive::VariantMap", "Parsing entry: {:?} with type {:x?}", name, &b[(pos)..(pos + 4)]);
let (vlen, value) = Variant::parse(&b[(pos)..])?;
pos += vlen;