diff options
| author | Max Audron <audron@cocaine.farm> | 2021-10-01 18:13:43 +0200 |
|---|---|---|
| committer | Max Audron <audron@cocaine.farm> | 2021-10-01 18:17:03 +0200 |
| commit | 8465010f3cb51d672b60df39a7dfd34624ab5c7c (patch) | |
| tree | 062d8640f7e7c4aea2a2e4029ea742982ba20911 | |
| parent | adapt Sync* types (diff) | |
migrate to separated NetworkMap and NetworkList macros
Diffstat (limited to '')
23 files changed, 371 insertions, 196 deletions
diff --git a/derive/src/from/mod.rs b/derive/src/from/mod.rs index 4b02f22..ee92016 100644 --- a/derive/src/from/mod.rs +++ b/derive/src/from/mod.rs @@ -8,7 +8,6 @@ use darling::{FromDeriveInput, FromVariant}; #[darling(attributes(from), supports(enum_any))] struct Enum { ident: syn::Ident, - attrs: Vec<syn::Attribute>, } #[derive(Debug, FromVariant)] diff --git a/derive/src/network/list.rs b/derive/src/network/list.rs index 8b1556e..79f9739 100644 --- a/derive/src/network/list.rs +++ b/derive/src/network/list.rs @@ -16,14 +16,21 @@ pub(crate) fn to(fields: &Vec<NetworkField>) -> Vec<TokenStream> { let field_type = get_field_variant_type(&field); let field_inner = if field.network { - quote! { self.#field_name.to_network() } + if field.map { + quote! { self.#field_name.to_network_map() } + } else { + match field.variant.as_ref().map_or("", |m| m.as_str()) { + "VariantMap" => quote! { self.#field_name.to_network_map() }, + &_ => quote! { self.#field_name.to_network() }, + } + } } else { quote! { self.#field_name.clone() } }; quote! { - res.push(crate::primitive::Variant::ByteArray(#field_rename.to_string())); - res.push(crate::primitive::Variant::#field_type(#field_inner)); + res.push(libquassel::primitive::Variant::ByteArray(#field_rename.to_string())); + res.push(libquassel::primitive::Variant::#field_type(#field_inner)); } }) .collect() @@ -47,20 +54,35 @@ pub(crate) fn from(fields: &Vec<NetworkField>) -> Vec<TokenStream> { let extract_inner = quote! { let mut i = input.iter(); - i.position(|x| *x == crate::primitive::Variant::ByteArray(String::from(#field_rename))) + i.position(|x| *x == libquassel::primitive::Variant::ByteArray(String::from(#field_rename))) .expect(format!("failed to get field {}", #field_rename).as_str()); match i.next().expect("failed to get next field") { - crate::primitive::Variant::#field_variant_type(var) => var.clone(), + libquassel::primitive::Variant::#field_variant_type(var) => var.clone(), _ => panic!("network::list::from: wrong variant type"), } }; if field.network { - quote! { - #field_name: #field_type_colon::from_network(&mut { - #extract_inner - }), + if field.map { + quote! { + #field_name: #field_type_colon::from_network_map(&mut { + #extract_inner + }), + } + } else { + match field.variant.as_ref().map_or("", |m| m.as_str()) { + "VariantMap" => quote! { + #field_name: #field_type_colon::from_network_map(&mut { + #extract_inner + }), + }, + &_ => quote! { + #field_name: #field_type_colon::from_network(&mut { + #extract_inner + }), + }, + } } } else { quote! { diff --git a/derive/src/network/map.rs b/derive/src/network/map.rs index 60f96b5..506ccb3 100644 --- a/derive/src/network/map.rs +++ b/derive/src/network/map.rs @@ -17,8 +17,19 @@ pub(crate) fn to(fields: &Vec<NetworkField>) -> Vec<TokenStream> { let field_variant_type = get_field_variant_type(&field); let field_inner = if field.network { - quote! { - self.#field_name.to_network() + if field.map { + quote! { + self.#field_name.to_network_map() + } + } else { + match field.variant.as_ref().map_or("", |m| m.as_str()) { + "VariantMap" => quote! { + self.#field_name.to_network_map() + }, + &_ => quote! { + self.#field_name.to_network() + }, + } } } else { quote! { @@ -28,7 +39,7 @@ pub(crate) fn to(fields: &Vec<NetworkField>) -> Vec<TokenStream> { quote! { res.insert(#field_rename.to_string(), - crate::primitive::Variant::#field_variant_type(#field_inner)); + libquassel::primitive::Variant::#field_variant_type(#field_inner)); } }) .collect() @@ -50,9 +61,23 @@ pub(crate) fn from(fields: &Vec<NetworkField>) -> Vec<TokenStream> { let field_type_colon = get_field_type_colon(field_type.clone()); if field.network { - quote! { - #field_name: #field_type_colon::from_network( - &mut std::convert::TryInto::try_into(input.remove(#field_rename).unwrap()).unwrap()), + if field.map { + quote! { + #field_name: #field_type_colon::from_network_map( + &mut std::convert::TryInto::try_into(input.remove(#field_rename).unwrap()).unwrap()), + } + } else { + match field.variant.as_ref().map_or("", |m| m.as_str()) { + "VariantMap" => quote! { + #field_name: #field_type_colon::from_network_map( + &mut std::convert::TryInto::try_into(input.remove(#field_rename).unwrap()).unwrap()), + }, + + &_ => quote! { + #field_name: #field_type_colon::from_network( + &mut std::convert::TryInto::try_into(input.remove(#field_rename).unwrap()).unwrap()), + } + } } } else { quote! { @@ -63,16 +88,36 @@ pub(crate) fn from(fields: &Vec<NetworkField>) -> Vec<TokenStream> { .collect() } -pub(crate) fn to_vec(_type_name: &Ident, _fields: &Vec<NetworkField>) -> TokenStream { - quote! { - self.iter().map(|item| { - item.to_network().into() - }).collect() +pub(crate) fn to_vec(_type_name: &Ident, _fields: &Vec<NetworkField>, new: bool) -> TokenStream { + if new { + quote! { + self.iter().map(|item| { + item.to_network_map().into() + }).collect() + } + } else { + quote! { + self.iter().map(|item| { + item.to_network().into() + }).collect() + } } } -pub(crate) fn from_vec(type_name: &Ident, _fields: &Vec<NetworkField>) -> TokenStream { - quote! { - input.iter().map(|item| #type_name::from_network(&mut std::convert::TryInto::try_into(item).unwrap())).collect() +pub(crate) fn from_vec(type_name: &Ident, _fields: &Vec<NetworkField>, new: bool) -> TokenStream { + if new { + quote! { + input.iter().map( + |item| #type_name::from_network_map( + &mut std::convert::TryInto::try_into(item).unwrap() + )).collect() + } + } else { + quote! { + input.iter().map( + |item| #type_name::from_network( + &mut std::convert::TryInto::try_into(item).unwrap() + )).collect() + } } } diff --git a/derive/src/network/maplist.rs b/derive/src/network/maplist.rs index 5b9b4d1..01d1e20 100644 --- a/derive/src/network/maplist.rs +++ b/derive/src/network/maplist.rs @@ -30,13 +30,13 @@ pub(crate) fn to(fields: &Vec<NetworkField>) -> Vec<TokenStream> { if let Some(_) = field.variant { quote! { res.insert(#field_rename.to_string(), - crate::primitive::Variant::#field_type( + libquassel::primitive::Variant::#field_type( std::vec::from_elem(#field_inner, 1))); } } else { quote! { res.insert(#field_rename.to_string(), - crate::primitive::Variant::VariantList( + libquassel::primitive::Variant::VariantList( std::vec::from_elem(#field_inner, 1))); } } @@ -61,8 +61,14 @@ pub(crate) fn to_vec(_type_name: &Ident, fields: &Vec<NetworkField>) -> TokenStr let field_type = get_field_variant_type(&field); let field_inner = if field.network { - quote! { - item.#field_name.to_network() + if field.map { + quote! { + item.#field_name.to_network_map() + } + } else { + quote! { + item.#field_name.to_network() + } } } else { quote! { @@ -72,7 +78,7 @@ pub(crate) fn to_vec(_type_name: &Ident, fields: &Vec<NetworkField>) -> TokenStr if let Some(_) = field.variant { lists.push(quote! { - let mut #field_name: crate::primitive::StringList = Vec::with_capacity(self.len()); + let mut #field_name: libquassel::primitive::StringList = Vec::with_capacity(self.len()); }); for_each_inner.push(quote! { @@ -80,19 +86,19 @@ pub(crate) fn to_vec(_type_name: &Ident, fields: &Vec<NetworkField>) -> TokenStr }); map_inserts.push(quote! { - map.insert(String::from(#field_rename), crate::primitive::Variant::StringList(#field_name)); + map.insert(String::from(#field_rename), libquassel::primitive::Variant::StringList(#field_name)); }); } else { lists.push(quote! { - let mut #field_name: crate::primitive::VariantList = Vec::with_capacity(self.len()); + let mut #field_name: libquassel::primitive::VariantList = Vec::with_capacity(self.len()); }); for_each_inner.push(quote! { - #field_name.push(crate::primitive::Variant::#field_type(#field_inner)); + #field_name.push(libquassel::primitive::Variant::#field_type(#field_inner)); }); map_inserts.push(quote! { - map.insert(String::from(#field_rename), crate::primitive::Variant::VariantList(#field_name)); + map.insert(String::from(#field_rename), libquassel::primitive::Variant::VariantList(#field_name)); }); } @@ -103,7 +109,7 @@ pub(crate) fn to_vec(_type_name: &Ident, fields: &Vec<NetworkField>) -> TokenStr quote! { #(#lists)* - let mut map = crate::primitive::VariantMap::new(); + let mut map = libquassel::primitive::VariantMap::new(); self.iter().for_each(|item| { #(#for_each_inner)* @@ -130,7 +136,7 @@ pub(crate) fn from(fields: &Vec<NetworkField>) -> Vec<TokenStream> { let field_inner = if field.network { quote! { - crate::message::Network::from_network(&mut std::convert::TryInto::try_into(input.remove(0)).unwrap()) + libquassel::message::Network::from_network(&mut std::convert::TryInto::try_into(input.remove(0)).unwrap()) } } else { quote! { @@ -141,14 +147,14 @@ pub(crate) fn from(fields: &Vec<NetworkField>) -> Vec<TokenStream> { if let Some(_) = field.variant { quote! { #field_name: match input.get_mut(#field_rename).unwrap() { - crate::primitive::Variant::#field_type(input) => #field_inner, + libquassel::primitive::Variant::#field_type(input) => #field_inner, _ => panic!("#field_name: wrong variant") }, } } else { quote! { #field_name: match input.get_mut(#field_rename).unwrap() { - crate::primitive::Variant::VariantList(input) => #field_inner, + libquassel::primitive::Variant::VariantList(input) => #field_inner, _ => panic!("#field_name: wrong variant") }, } @@ -157,7 +163,7 @@ pub(crate) fn from(fields: &Vec<NetworkField>) -> Vec<TokenStream> { .collect() } -pub(crate) fn from_vec(type_name: &Ident, fields: &Vec<NetworkField>) -> TokenStream { +pub(crate) fn from_vec(type_name: &Ident, fields: &Vec<NetworkField>, new: bool) -> TokenStream { let field = &fields[0]; let field_rename = match &field.rename { @@ -170,20 +176,30 @@ pub(crate) fn from_vec(type_name: &Ident, fields: &Vec<NetworkField>) -> TokenSt let _field_type = get_field_variant_type(field); let field_variant = match &field.variant { - None => quote! {crate::primitive::VariantList}, + None => quote! {libquassel::primitive::VariantList}, Some(variant_type) => match variant_type.as_str() { - "StringList" => quote! {crate::primitive::StringList}, - "VariantMap" => quote! {crate::primitive::VariantMap}, - _ => quote! {crate::primitive::VariantMap}, + "StringList" => quote! {libquassel::primitive::StringList}, + "VariantMap" => quote! {libquassel::primitive::VariantMap}, + _ => quote! {libquassel::primitive::VariantMap}, }, }; + let inner = if new { + quote! { + #type_name::from_network_map(input) + } + } else { + quote! { + #type_name::from_network(input) + } + }; + quote! { let marker: #field_variant = std::convert::TryInto::try_into(input.get(#field_rename).unwrap()).unwrap(); let mut res = Vec::new(); for _ in 0..marker.len() { - res.push(#type_name::from_network(input)); + res.push(#inner); } return res; diff --git a/derive/src/network/mod.rs b/derive/src/network/mod.rs index dd861ea..15f2d18 100644 --- a/derive/src/network/mod.rs +++ b/derive/src/network/mod.rs @@ -11,8 +11,6 @@ mod maplist; #[darling(attributes(network), supports(struct_any))] /// Derive to and from network methods for quassel objects pub struct Network { - ident: syn::Ident, - attrs: Vec<syn::Attribute>, /// Representation to choose for the network format /// see Repr enum #[darling(default)] @@ -22,7 +20,7 @@ pub struct Network { /// List: /// Map: /// Maplist: -#[derive(Debug, Clone, Copy, FromMeta)] +#[derive(Debug, Clone, Copy, PartialEq, FromMeta)] pub enum Repr { List, Map, @@ -55,6 +53,10 @@ pub struct NetworkField { /// use to_network and from_network on it #[darling(default)] network: bool, + /// When network is true, use map + /// network representation for this field + #[darling(default)] + map: bool, } fn parse_fields(input: &syn::DeriveInput) -> Vec<NetworkField> { @@ -90,17 +92,19 @@ pub fn network_map(input: proc_macro::TokenStream) -> proc_macro::TokenStream { Repr::Map | _ => map::from(&fields), }; - let gen = quote! { - impl crate::message::signalproxy::NetworkMap for #name { - fn to_network_map(&self) -> VariantMap { - let mut res = VariantMap::new(); + let mut gen = quote! { + impl libquassel::message::signalproxy::NetworkMap for #name { + type Item = libquassel::primitive::VariantMap; + + fn to_network_map(&self) -> libquassel::primitive::VariantMap { + let mut res = libquassel::primitive::VariantMap::new(); #(#to_network_map)* return res; } - fn from_network_map(input: &mut VariantMap) -> Self { + fn from_network_map(input: &mut libquassel::primitive::VariantMap) -> Self { Self { #(#from_network_map)* } @@ -108,13 +112,47 @@ pub fn network_map(input: proc_macro::TokenStream) -> proc_macro::TokenStream { } }; + let network_map_vec_item = match network.repr { + Repr::Map => quote! {libquassel::primitive::VariantList}, + Repr::Maplist => quote! {libquassel::primitive::VariantMap}, + Repr::List => quote! {libquassel::primitive::VariantList}, + }; + + let to_network_map_vec = match network.repr { + Repr::Maplist => maplist::to_vec(name, &fields), + Repr::Map => map::to_vec(name, &fields, true), + _ => unimplemented!(), + }; + + let from_network_map_vec = match network.repr { + Repr::Maplist => maplist::from_vec(name, &fields, true), + Repr::Map => map::from_vec(name, &fields, true), + _ => unimplemented!(), + }; + + let list_map = quote! { + impl libquassel::message::signalproxy::NetworkMap for Vec<#name> { + type Item = #network_map_vec_item; + + fn to_network_map(&self) -> Self::Item { + #to_network_map_vec + } + + fn from_network_map(input: &mut Self::Item) -> Self { + #from_network_map_vec + } + } + }; + + gen.extend(list_map); + gen.into() } pub fn network_list(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let input = parse_macro_input!(input as syn::DeriveInput); - let network = Network::from_derive_input(&input).unwrap(); + let _network = Network::from_derive_input(&input).unwrap(); let fields = parse_fields(&input); @@ -124,16 +162,16 @@ pub fn network_list(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let from_network_list = list::from(&fields); let gen = quote! { - impl crate::message::signalproxy::NetworkList for #name { - fn to_network_list(&self) -> VariantList { - let mut res = VariantList::new(); + impl libquassel::message::signalproxy::NetworkList for #name { + fn to_network_list(&self) -> libquassel::primitive::VariantList { + let mut res = libquassel::primitive::VariantList::new(); #(#to_network_list)* return res; } - fn from_network_list(input: &mut VariantList) -> Self { + fn from_network_list(input: &mut libquassel::primitive::VariantList) -> Self { Self { #(#from_network_list)* } @@ -172,13 +210,13 @@ pub fn network(input: proc_macro::TokenStream) -> proc_macro::TokenStream { }; let network_impl_item = match network.repr { - Repr::Map => quote! {crate::primitive::VariantMap;}, - Repr::Maplist => quote! {crate::primitive::VariantMap;}, - Repr::List => quote! {crate::primitive::VariantList;}, + Repr::Map => quote! {libquassel::primitive::VariantMap;}, + Repr::Maplist => quote! {libquassel::primitive::VariantMap;}, + Repr::List => quote! {libquassel::primitive::VariantList;}, }; let mut gen = quote! { - impl crate::message::signalproxy::Network for #name { + impl libquassel::message::signalproxy::Network for #name { type Item = #network_impl_item fn to_network(&self) -> Self::Item { @@ -199,25 +237,25 @@ pub fn network(input: proc_macro::TokenStream) -> proc_macro::TokenStream { if let Repr::Maplist | Repr::Map = network.repr { let network_impl_item_vec = match network.repr { - Repr::Map => quote! {crate::primitive::VariantList;}, - Repr::Maplist => quote! {crate::primitive::VariantMap;}, - Repr::List => quote! {crate::primitive::VariantList;}, + Repr::Map => quote! {libquassel::primitive::VariantList;}, + Repr::Maplist => quote! {libquassel::primitive::VariantMap;}, + Repr::List => quote! {libquassel::primitive::VariantList;}, }; let to_network_impl_vec_center = match network.repr { Repr::Maplist => maplist::to_vec(name, &fields), - Repr::Map => map::to_vec(name, &fields), + Repr::Map => map::to_vec(name, &fields, false), _ => unimplemented!(), }; let from_network_impl_vec_center = match network.repr { - Repr::Maplist => maplist::from_vec(name, &fields), - Repr::Map => map::from_vec(name, &fields), + Repr::Maplist => maplist::from_vec(name, &fields, false), + Repr::Map => map::from_vec(name, &fields, false), _ => unimplemented!(), }; let vec = quote! { - impl crate::message::signalproxy::Network for Vec<#name> { + impl libquassel::message::signalproxy::Network for Vec<#name> { type Item = #network_impl_item_vec fn to_network(&self) -> Self::Item { @@ -2,6 +2,8 @@ #![feature(doc_cfg)] #[doc = include_str!("../README.md")] #[cfg_attr(docsrs, feature(doc_cfg))] +extern crate self as libquassel; + #[macro_use] mod util; diff --git a/src/message/handshake/sessioninit.rs b/src/message/handshake/sessioninit.rs index a663cce..fa99f32 100644 --- a/src/message/handshake/sessioninit.rs +++ b/src/message/handshake/sessioninit.rs @@ -20,13 +20,13 @@ pub struct SessionInit { impl From<VariantMap> for SessionInit { fn from(input: VariantMap) -> Self { - use crate::message::signalproxy::Network; + use crate::message::signalproxy::NetworkMap; let state: VariantMap = input.get("SessionState").unwrap().try_into().unwrap(); log::trace!("sessionstate: {:#?}", state); SessionInit { - identities: Vec::<Identity>::from_network( + identities: Vec::<Identity>::from_network_map( &mut state.get("Identities").unwrap().try_into().unwrap(), ), buffers: match_variant!(state.get("BufferInfos").unwrap(), Variant::VariantList) diff --git a/src/message/signalproxy/mod.rs b/src/message/signalproxy/mod.rs index 41057ca..d5cdd80 100644 --- a/src/message/signalproxy/mod.rs +++ b/src/message/signalproxy/mod.rs @@ -1,10 +1,7 @@ -use std::convert::TryInto; - use crate::{ deserialize::Deserialize, - primitive::{VariantList, VariantMap}, + primitive::{Variant, VariantList}, serialize::Serialize, - session::Session, }; use num_derive::{FromPrimitive, ToPrimitive}; @@ -63,9 +60,14 @@ pub trait Syncable { /// A Stateful Syncable Object #[allow(unused_variables)] -pub trait StatefulSyncable: Syncable + translation::NetworkMap { +pub trait StatefulSyncable: Syncable + translation::NetworkMap +// where +// <T as Iterator>::Item: ToString, +where + Variant: From<<Self as translation::NetworkMap>::Item>, +{ /// Client -> Server: Update the whole object with received data - fn update(&mut self, session: impl SyncProxy, param: VariantMap) + fn update(&mut self, session: impl SyncProxy, param: <Self as translation::NetworkMap>::Item) where Self: Sized, { @@ -80,8 +82,11 @@ pub trait StatefulSyncable: Syncable + translation::NetworkMap { } /// Server -> Client: Update the whole object with received data - fn request_update(&mut self, session: impl SyncProxy, mut param: VariantMap) - where + fn request_update( + &mut self, + session: impl SyncProxy, + mut param: <Self as translation::NetworkMap>::Item, + ) where Self: Sized, { #[cfg(feature = "client")] diff --git a/src/message/signalproxy/objects/aliasmanager.rs b/src/message/signalproxy/objects/aliasmanager.rs index cb634ba..d696aae 100644 --- a/src/message/signalproxy/objects/aliasmanager.rs +++ b/src/message/signalproxy/objects/aliasmanager.rs @@ -1,18 +1,17 @@ use std::convert::TryInto; -use libquassel_derive::{Network, NetworkList, NetworkMap}; +use libquassel_derive::{NetworkList, NetworkMap}; use crate::message::{StatefulSyncable, SyncProxy, Syncable}; -use crate::message::signalproxy::translation::{Network, NetworkMap}; -use crate::primitive::{VariantList, VariantMap}; +use crate::message::signalproxy::translation::NetworkMap; /// AliasManager /// keeps a list of all registered aliases /// syncable #[derive(Clone, Debug, std::cmp::PartialEq, NetworkList, NetworkMap)] pub struct AliasManager { - #[network(rename = "Aliases", variant = "VariantMap", network)] + #[network(rename = "Aliases", variant = "VariantMap", network, map)] pub aliases: Vec<Alias>, } @@ -51,7 +50,7 @@ impl Syncable for AliasManager { /// Alias /// Represents a signle alias -#[derive(Clone, Debug, std::cmp::PartialEq, Network)] +#[derive(Clone, Debug, std::cmp::PartialEq, NetworkMap)] #[network(repr = "maplist")] pub struct Alias { #[network(rename = "names", variant = "StringList")] diff --git a/src/message/signalproxy/objects/buffersyncer.rs b/src/message/signalproxy/objects/buffersyncer.rs index ecacbc9..62ee793 100644 --- a/src/message/signalproxy/objects/buffersyncer.rs +++ b/src/message/signalproxy/objects/buffersyncer.rs @@ -1,9 +1,11 @@ use std::collections::HashMap; use crate::primitive::MessageType; -use libquassel_derive::Network; +use libquassel_derive::NetworkList; -#[derive(Debug, Clone, PartialEq, Network)] +use crate::message::signalproxy::translation::Network; + +#[derive(Debug, Clone, PartialEq, NetworkList)] #[network(repr = "list")] pub struct BufferSyncer { #[network(rename = "Activities", network, variant = "VariantList")] @@ -82,7 +84,7 @@ pub trait BufferSyncerClient { #[cfg(test)] mod tests { use super::*; - use crate::message::signalproxy::translation::Network; + use crate::message::signalproxy::translation::NetworkList; use crate::primitive::{Variant, VariantList}; use pretty_assertions::assert_eq; @@ -185,7 +187,7 @@ mod tests { #[test] fn buffersyncer_from_network() { assert_eq!( - BufferSyncer::from_network(&mut get_network()), + BufferSyncer::from_network_list(&mut get_network()), get_runtime() ) } diff --git a/src/message/signalproxy/objects/bufferview.rs b/src/message/signalproxy/objects/bufferview.rs index 512a5b9..5ac608c 100644 --- a/src/message/signalproxy/objects/bufferview.rs +++ b/src/message/signalproxy/objects/bufferview.rs @@ -1,6 +1,8 @@ -use libquassel_derive::Network; use std::{collections::HashMap, convert::TryInto}; +use libquassel_derive::NetworkList; + +use crate::message::signalproxy::translation::Network; use crate::primitive::{Variant, VariantList}; #[derive(Debug, Clone, PartialEq)] @@ -27,10 +29,8 @@ pub struct BufferViewManager { // update(properties: QVariantMap) } -impl super::Network for BufferViewManager { - type Item = VariantList; - - fn to_network(&self) -> Self::Item { +impl super::NetworkList for BufferViewManager { + fn to_network_list(&self) -> VariantList { let mut res = Vec::with_capacity(2); res.push(Variant::ByteArray(s!("bufferViewIds"))); @@ -44,7 +44,7 @@ impl super::Network for BufferViewManager { return res; } - fn from_network(_input: &mut Self::Item) -> Self { + fn from_network_list(_input: &mut VariantList) -> Self { // TODO Somehow do the initrequests for all the IDs we get here Self { buffer_view_configs: HashMap::new(), @@ -52,8 +52,7 @@ impl super::Network for BufferViewManager { } } -#[derive(Debug, Clone, PartialEq, Network)] -#[network(repr = "list")] +#[derive(Debug, Clone, PartialEq, NetworkList)] pub struct BufferViewConfig { #[network(rename = "BufferList", network, variant = "VariantList")] pub buffers: Vec<i32>, diff --git a/src/message/signalproxy/objects/certmanager.rs b/src/message/signalproxy/objects/certmanager.rs index 238c495..d105fcf 100644 --- a/src/message/signalproxy/objects/certmanager.rs +++ b/src/message/signalproxy/objects/certmanager.rs @@ -1,7 +1,6 @@ -use libquassel_derive::Network; +use libquassel_derive::NetworkList; -#[derive(Debug, Clone, PartialEq, Network)] -#[network(repr = "list")] +#[derive(Debug, Clone, PartialEq, NetworkList)] pub struct CertManager { #[network(rename = "sslKey", variant = "ByteArray")] pub ssl_key: String, diff --git a/src/message/signalproxy/objects/coreinfo.rs b/src/message/signalproxy/objects/coreinfo.rs index a717366..ef9826f 100644 --- a/src/message/signalproxy/objects/coreinfo.rs +++ b/src/message/signalproxy/objects/coreinfo.rs @@ -1,11 +1,11 @@ -use libquassel_derive::Network; +use libquassel_derive::NetworkMap; use crate::primitive::{DateTime, StringList}; -#[derive(Debug, Clone, PartialEq, Network)] +#[derive(Debug, Clone, PartialEq, NetworkMap)] #[network(repr = "map")] pub struct CoreInfo { - #[network(rename = "coreData", network, variant = "VariantMap")] + #[network(rename = "coreData", variant = "VariantMap", network)] core_data: CoreData, } @@ -17,7 +17,7 @@ pub struct CoreInfo { // */ // update(properties: QVariantMap) -#[derive(Debug, Clone, PartialEq, Network)] +#[derive(Debug, Clone, PartialEq, NetworkMap)] #[network(repr = "map")] pub struct CoreData { #[network(rename = "quasselVersion")] @@ -31,12 +31,13 @@ pub struct CoreData { #[network( rename = "sessionConnectedClientData", variant = "VariantList", - network + network, + map )] session_connected_client_data: Vec<ConnectedClient>, } -#[derive(Debug, Clone, PartialEq, Network)] +#[derive(Debug, Clone, PartialEq, NetworkMap)] #[network(repr = "map")] pub struct ConnectedClient { #[network(rename = "id")] diff --git a/src/message/signalproxy/objects/highlightrulemanager.rs b/src/message/signalproxy/objects/highlightrulemanager.rs index e6429d2..ef64a2c 100644 --- a/src/message/signalproxy/objects/highlightrulemanager.rs +++ b/src/message/signalproxy/objects/highlightrulemanager.rs @@ -1,20 +1,21 @@ -use libquassel_derive::Network; +use libquassel_derive::{NetworkList, NetworkMap}; + +use crate::message::signalproxy::translation::{Network, NetworkMap}; use num_derive::{FromPrimitive, ToPrimitive}; use num_traits::{FromPrimitive, ToPrimitive}; -#[derive(Debug, Clone, PartialEq, Network)] -#[network(repr = "list")] +#[derive(Debug, Clone, PartialEq, NetworkList)] pub struct HighlightRuleManager { - #[network(rename = "HighlightRuleList", network, variant = "VariantMap")] + #[network(rename = "HighlightRuleList", variant = "VariantMap", network, map)] highlight_rule_list: Vec<HighlightRule>, - #[network(rename = "highlightNick", network, variant = "i32")] + #[network(rename = "highlightNick", variant = "i32", network)] highlight_nick: HighlightNickType, #[network(rename = "nicksCaseSensitive")] nicks_case_sensitive: bool, } -#[derive(Debug, Clone, PartialEq, Network)] +#[derive(Debug, Clone, PartialEq, NetworkMap)] #[network(repr = "maplist")] pub struct HighlightRule { id: i32, @@ -56,7 +57,7 @@ impl crate::message::signalproxy::Network for HighlightNickType { #[cfg(test)] mod tests { use super::*; - use crate::message::signalproxy::translation::Network; + use crate::message::signalproxy::translation::NetworkList; use crate::primitive::{Variant, VariantList}; use pretty_assertions::assert_eq; @@ -100,13 +101,13 @@ mod tests { #[test] fn highlightrulemanager_to_network() { - assert_eq!(get_runtime().to_network(), get_network()) + assert_eq!(get_runtime().to_network_list(), get_network()) } #[test] fn highlightrulemanager_from_network() { assert_eq!( - HighlightRuleManager::from_network(&mut get_network()), + HighlightRuleManager::from_network_list(&mut get_network()), get_runtime() ) } diff --git a/src/message/signalproxy/objects/identity.rs b/src/message/signalproxy/objects/identity.rs index 3c05c87..e173689 100644 --- a/src/message/signalproxy/objects/identity.rs +++ b/src/message/signalproxy/objects/identity.rs @@ -1,7 +1,6 @@ -use libquassel_derive::Network; +use libquassel_derive::NetworkMap; -#[derive(Debug, Clone, PartialEq, Network)] -#[network(repr = "map")] +#[derive(Debug, Clone, PartialEq, NetworkMap)] pub struct Identity { #[network(rename = "identityId")] identity_id: i32, diff --git a/src/message/signalproxy/objects/ignorelistmanager.rs b/src/message/signalproxy/objects/ignorelistmanager.rs index f98ed36..a3d9798 100644 --- a/src/message/signalproxy/objects/ignorelistmanager.rs +++ b/src/message/signalproxy/objects/ignorelistmanager.rs @@ -1,10 +1,11 @@ -use libquassel_derive::Network; +use crate::message::signalproxy::translation::{Network, NetworkMap}; +use libquassel_derive::{NetworkList, NetworkMap}; + use std::convert::TryFrom; -#[derive(Debug, Clone, PartialEq, Network)] -#[network(repr = "list")] +#[derive(Debug, Clone, PartialEq, NetworkList)] pub struct IgnoreListManager { - #[network(rename = "IgnoreList", network, variant = "VariantMap")] + #[network(rename = "IgnoreList", variant = "VariantMap", network, map)] ignore_list: Vec<IgnoreListItem>, // // C->S calls @@ -32,7 +33,7 @@ pub struct IgnoreListManager { // update(properties: QVariantMap) } -#[derive(Debug, Clone, PartialEq, Network)] +#[derive(Debug, Clone, PartialEq, NetworkMap)] #[network(repr = "maplist")] pub struct IgnoreListItem { #[network(rename = "ignoreType", network, type = "u8")] @@ -76,7 +77,7 @@ impl TryFrom<u8> for IgnoreType { } } -impl super::Network for IgnoreType { +impl crate::message::signalproxy::Network for IgnoreType { type Item = u8; fn to_network(&self) -> Self::Item { @@ -109,7 +110,7 @@ impl TryFrom<u8> for StrictnessType { } } -impl super::Network for StrictnessType { +impl crate::message::signalproxy::Network for StrictnessType { type Item = u8; fn to_network(&self) -> Self::Item { @@ -142,7 +143,7 @@ impl TryFrom<u8> for ScopeType { } } -impl super::Network for ScopeType { +impl crate::message::signalproxy::Network for ScopeType { type Item = u8; fn to_network(&self) -> Self::Item { diff --git a/src/message/signalproxy/objects/ircchannel.rs b/src/message/signalproxy/objects/ircchannel.rs index ee23f07..16f1f10 100644 --- a/src/message/signalproxy/objects/ircchannel.rs +++ b/src/message/signalproxy/objects/ircchannel.rs @@ -2,10 +2,9 @@ use std::collections::HashMap; use std::convert::TryFrom; use std::convert::TryInto; +use crate::message::NetworkMap; use crate::primitive::{StringList, Variant, VariantList, VariantMap}; -use crate::message::signalproxy::Network; - #[allow(dead_code)] #[derive(Debug, Clone, PartialEq)] pub struct IrcChannel { @@ -29,10 +28,10 @@ pub struct IrcChannel { // D(char), // } -impl Network for Vec<IrcChannel> { +impl NetworkMap for Vec<IrcChannel> { type Item = VariantMap; - fn to_network(&self) -> Self::Item { + fn to_network_map(&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()); @@ -103,23 +102,23 @@ impl Network for Vec<IrcChannel> { map } - fn from_network(input: &mut Self::Item) -> Self { + fn from_network_map(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)); + res.push(IrcChannel::from_network_map(input)); } return res; } } -impl Network for IrcChannel { +impl NetworkMap for IrcChannel { type Item = VariantMap; - fn to_network(&self) -> Self::Item { + fn to_network_map(&self) -> Self::Item { let mut res = VariantMap::new(); res.insert( @@ -188,7 +187,7 @@ impl Network for IrcChannel { res } - fn from_network(input: &mut Self::Item) -> Self { + fn from_network_map(input: &mut Self::Item) -> Self { let mut chanmodes: VariantMap = match_variant!( match_variant!(input.get_mut("ChanModes").unwrap(), Variant::VariantList).remove(0), Variant::VariantMap @@ -334,11 +333,14 @@ mod tests { #[test] fn ircchannel_to_network() { - assert_eq!(get_runtime().to_network(), get_network()) + assert_eq!(get_runtime().to_network_map(), get_network()) } #[test] fn ircchannel_from_network() { - assert_eq!(IrcChannel::from_network(&mut get_network()), get_runtime()) + assert_eq!( + IrcChannel::from_network_map(&mut get_network()), + get_runtime() + ) } } diff --git a/src/message/signalproxy/objects/ircuser.rs b/src/message/signalproxy/objects/ircuser.rs index 85fea81..6b14c70 100644 --- a/src/message/signalproxy/objects/ircuser.rs +++ b/src/message/signalproxy/objects/ircuser.rs @@ -2,10 +2,10 @@ use crate::primitive::{DateTime, StringList}; #[allow(unused_imports)] use crate::message::signalproxy::Network; -use libquassel_derive::Network; +use libquassel_derive::NetworkMap; #[allow(dead_code)] -#[derive(Debug, Clone, PartialEq, Network)] +#[derive(Debug, Clone, PartialEq, NetworkMap)] #[network(repr = "maplist")] pub struct IrcUser { pub user: String, @@ -38,6 +38,7 @@ pub struct IrcUser { #[cfg(test)] mod tests { + use crate::message::signalproxy::NetworkMap; use crate::primitive::{Variant, VariantMap}; use time::OffsetDateTime; @@ -191,16 +192,16 @@ mod tests { #[test] fn ircuser_to_network() { - assert_eq!(get_runtime().to_network(), get_network()) + assert_eq!(get_runtime().to_network_map(), get_network()) } #[test] fn ircuser_from_network() { - assert_eq!(IrcUser::from_network(&mut get_network()), get_runtime()) + assert_eq!(IrcUser::from_network_map(&mut get_network()), get_runtime()) } #[test] fn vec_ircuser_to_network() { - assert_eq!(get_runtime().to_network(), get_network()) + assert_eq!(get_runtime().to_network_map(), get_network()) } } diff --git a/src/message/signalproxy/objects/mod.rs b/src/message/signalproxy/objects/mod.rs index 72737a0..20c78a2 100644 --- a/src/message/signalproxy/objects/mod.rs +++ b/src/message/signalproxy/objects/mod.rs @@ -29,7 +29,7 @@ pub use networkinfo::*; use libquassel_derive::From; use log::debug; -use super::{Network, NetworkList}; +use super::{NetworkList, NetworkMap}; use crate::primitive::VariantList; /// Central Enum containing and identifying all Quassel Protocol Types: @@ -73,17 +73,17 @@ impl Types { debug!("converting to network object: {:#?}", self); match self { Types::AliasManager(val) => val.to_network_list(), - Types::BufferSyncer(val) => val.to_network(), - Types::BufferViewConfig(val) => val.to_network(), - Types::BufferViewManager(val) => val.to_network(), - Types::CoreInfo(val) => vec![val.to_network().into()], - Types::CoreData(val) => vec![val.to_network().into()], - Types::HighlightRuleManager(val) => val.to_network(), - Types::IgnoreListManager(val) => val.to_network(), - Types::CertManager(val) => val.to_network(), - Types::Network(val) => val.to_network(), - Types::NetworkInfo(val) => val.to_network(), - Types::NetworkConfig(val) => val.to_network(), + Types::BufferSyncer(val) => val.to_network_list(), + Types::BufferViewConfig(val) => val.to_network_list(), + Types::BufferViewManager(val) => val.to_network_list(), + Types::CoreInfo(val) => vec![val.to_network_map().into()], + Types::CoreData(val) => vec![val.to_network_map().into()], + Types::HighlightRuleManager(val) => val.to_network_list(), + Types::IgnoreListManager(val) => val.to_network_list(), + Types::CertManager(val) => val.to_network_list(), + Types::Network(val) => val.to_network_list(), + Types::NetworkInfo(val) => val.to_network_list(), + Types::NetworkConfig(val) => val.to_network_list(), Types::Unknown(val) => val.clone(), } } @@ -95,23 +95,29 @@ impl Types { ); match class_name { "AliasManager" => Types::AliasManager(AliasManager::from_network_list(input)), - "BufferSyncer" => Types::BufferSyncer(BufferSyncer::from_network(input)), - "BufferViewConfig" => Types::BufferViewConfig(BufferViewConfig::from_network(input)), - "BufferViewManager" => Types::BufferViewManager(BufferViewManager::from_network(input)), - "CoreInfo" => Types::CoreInfo(CoreInfo::from_network( + "BufferSyncer" => Types::BufferSyncer(BufferSyncer::from_network_list(input)), + "BufferViewConfig" => { + Types::BufferViewConfig(BufferViewConfig::from_network_list(input)) + } + "BufferViewManager" => { + Types::BufferViewManager(BufferViewManager::from_network_list(input)) + } + "CoreInfo" => Types::CoreInfo(CoreInfo::from_network_map( &mut input.remove(0).try_into().unwrap(), )), - "CoreData" => Types::CoreData(CoreData::from_network( + "CoreData" => Types::CoreData(CoreData::from_network_map( &mut input.remove(0).try_into().unwrap(), )), "HighlightRuleManager" => { - Types::HighlightRuleManager(HighlightRuleManager::from_network(input)) + Types::HighlightRuleManager(HighlightRuleManager::from_network_list(input)) + } + "IgnoreListManager" => { + Types::IgnoreListManager(IgnoreListManager::from_network_list(input)) } - "IgnoreListManager" => Types::IgnoreListManager(IgnoreListManager::from_network(input)), - "CertManager" => Types::CertManager(CertManager::from_network(input)), - "Network" => Types::Network(Network::from_network(input)), - "NetworkInfo" => Types::NetworkInfo(NetworkInfo::from_network(input)), - "NetworkConfig" => Types::NetworkConfig(NetworkConfig::from_network(input)), + "CertManager" => Types::CertManager(CertManager::from_network_list(input)), + "Network" => Types::Network(Network::from_network_list(input)), + "NetworkInfo" => Types::NetworkInfo(NetworkInfo::from_network_list(input)), + "NetworkConfig" => Types::NetworkConfig(NetworkConfig::from_network_list(input)), _ => Types::Unknown(input.to_owned()), } } diff --git a/src/message/signalproxy/objects/network.rs b/src/message/signalproxy/objects/network.rs index cecc412..2fa4c49 100644 --- a/src/message/signalproxy/objects/network.rs +++ b/src/message/signalproxy/objects/network.rs @@ -1,14 +1,14 @@ -use std::convert::TryInto; - -use crate::primitive::{Variant, VariantList, VariantMap}; - -use libquassel_derive::Network; - use std::collections::HashMap; +use std::convert::TryInto; use num_derive::{FromPrimitive, ToPrimitive}; use num_traits::FromPrimitive; +use libquassel_derive::{NetworkList, NetworkMap}; + +use crate::message::signalproxy::translation::NetworkMap; +use crate::primitive::{Variant, VariantList, VariantMap}; + use super::{ircchannel::IrcChannel, ircuser::IrcUser, networkinfo::NetworkInfo}; #[derive(Debug, Clone, PartialEq)] @@ -29,11 +29,9 @@ pub struct Network { network_info: NetworkInfo, } -impl crate::message::signalproxy::Network for Network { - type Item = VariantList; - - fn to_network(&self) -> Self::Item { - let mut res = Self::Item::new(); +impl crate::message::signalproxy::NetworkList for Network { + fn to_network_list(&self) -> VariantList { + let mut res = VariantList::new(); res.push(Variant::ByteArray(s!("myNick"))); res.push(Variant::String(self.my_nick.clone())); @@ -78,7 +76,7 @@ impl crate::message::signalproxy::Network for Network { Variant::VariantMap(self.irc_users.iter().fold( HashMap::new(), |mut res, (_, v)| { - res.extend(v.to_network()); + res.extend(v.to_network_map()); res }, @@ -89,7 +87,7 @@ impl crate::message::signalproxy::Network for Network { .irc_channels .iter() .fold(HashMap::new(), |mut res, (_, v)| { - res.extend(v.to_network()); + res.extend(v.to_network_map()); res }); @@ -100,12 +98,12 @@ impl crate::message::signalproxy::Network for Network { res.push(Variant::VariantMap(map)); } - res.extend(self.network_info.to_network()); + res.extend(self.network_info.to_network_list()); res } - fn from_network(input: &mut Self::Item) -> Self { + fn from_network_list(input: &mut VariantList) -> Self { let mut i = input.iter().cycle(); let users_and_channels: VariantMap = { @@ -152,7 +150,7 @@ impl crate::message::signalproxy::Network for Network { irc_users: { match users_and_channels.get("Users") { Some(users) => { - let users: Vec<IrcUser> = Vec::<IrcUser>::from_network( + let users: Vec<IrcUser> = Vec::<IrcUser>::from_network_map( &mut users.try_into().expect("failed to convert Users"), ); @@ -168,7 +166,7 @@ impl crate::message::signalproxy::Network for Network { match users_and_channels.get("Channels") { Some(channels) => { let channels: Vec<IrcChannel> = - Vec::<IrcChannel>::from_network(&mut channels.try_into().unwrap()); + Vec::<IrcChannel>::from_network_map(&mut channels.try_into().unwrap()); channels .into_iter() .map(|channel| (channel.name.clone(), channel)) @@ -205,13 +203,12 @@ impl crate::message::signalproxy::Network for Network { var.into_iter().map(|v| v.try_into().unwrap()).collect() }, - network_info: NetworkInfo::from_network(input), + network_info: NetworkInfo::from_network_list(input), } } } -#[derive(Debug, Clone, PartialEq, Network)] -#[network(repr = "map")] +#[derive(Debug, Clone, PartialEq, NetworkMap)] pub struct NetworkServer { #[network(rename = "Host")] pub host: String, @@ -239,8 +236,7 @@ pub struct NetworkServer { pub proxy_pass: String, } -#[derive(Debug, Clone, PartialEq, Network)] -#[network(repr = "list")] +#[derive(Debug, Clone, PartialEq, NetworkList)] pub struct NetworkConfig { #[network(rename = "pingTimeoutEnabled")] ping_timeout_enabled: bool, @@ -263,7 +259,6 @@ pub struct NetworkConfig { #[cfg(test)] mod tests { use super::*; - use crate::message::signalproxy::translation::Network; fn networkserver_get_network() -> VariantMap { map! { @@ -325,7 +320,7 @@ mod tests { #[test] fn network_server_to_network() { assert_eq!( - networkserver_get_runtime().to_network(), + networkserver_get_runtime().to_network_map(), networkserver_get_network() ) } diff --git a/src/message/signalproxy/objects/networkinfo.rs b/src/message/signalproxy/objects/networkinfo.rs index 49351ad..23a001d 100644 --- a/src/message/signalproxy/objects/networkinfo.rs +++ b/src/message/signalproxy/objects/networkinfo.rs @@ -1,16 +1,16 @@ use crate::primitive::StringList; -use libquassel_derive::Network; +use libquassel_derive::NetworkList; use crate::message::objects::network::NetworkServer; +use crate::message::signalproxy::translation::NetworkMap; -#[derive(Debug, Clone, PartialEq, Network)] -#[network(repr = "list")] +#[derive(Debug, Clone, PartialEq, NetworkList)] pub struct NetworkInfo { #[network(rename = "networkName")] pub network_name: String, - #[network(rename = "ServerList", network, variant = "VariantList")] + #[network(rename = "ServerList", variant = "VariantList", network, map)] pub server_list: Vec<NetworkServer>, #[network(rename = "perform")] pub perform: StringList, @@ -71,7 +71,7 @@ mod tests { use crate::primitive::{Variant, VariantList}; use super::*; - use crate::message::signalproxy::translation::Network; + use crate::message::signalproxy::translation::NetworkList; use pretty_assertions::assert_eq; @@ -154,11 +154,14 @@ mod tests { #[test] fn networkinfo_to_network() { - assert_eq!(get_runtime().to_network(), get_network()) + assert_eq!(get_runtime().to_network_list(), get_network()) } #[test] fn networkinfo_from_network() { - assert_eq!(NetworkInfo::from_network(&mut get_network()), get_runtime()) + assert_eq!( + NetworkInfo::from_network_list(&mut get_network()), + get_runtime() + ) } } diff --git a/src/message/signalproxy/translation/mod.rs b/src/message/signalproxy/translation/mod.rs index 3587ab6..f6bbbb9 100644 --- a/src/message/signalproxy/translation/mod.rs +++ b/src/message/signalproxy/translation/mod.rs @@ -84,7 +84,7 @@ VariantMap({ }) ``` **/ -use crate::primitive::{VariantList, VariantMap}; +use crate::primitive::VariantList; pub trait Network { type Item; @@ -94,8 +94,10 @@ pub trait Network { } pub trait NetworkMap { - fn to_network_map(&self) -> VariantMap; - fn from_network_map(input: &mut VariantMap) -> Self; + type Item; + + fn to_network_map(&self) -> Self::Item; + fn from_network_map(input: &mut Self::Item) -> Self; } pub trait NetworkList { diff --git a/src/primitive/variant.rs b/src/primitive/variant.rs index d49f0dc..92e3211 100644 --- a/src/primitive/variant.rs +++ b/src/primitive/variant.rs @@ -141,6 +141,44 @@ where } } +impl<T, S> crate::message::NetworkMap for HashMap<T, S> +where + T: std::convert::TryFrom<Variant> + Into<Variant> + Clone + std::hash::Hash + std::cmp::Eq, + S: std::convert::TryFrom<Variant> + Into<Variant> + Clone + std::hash::Hash + std::cmp::Eq, +{ + type Item = super::VariantList; + + fn to_network_map(&self) -> Self::Item { + let mut res = Vec::with_capacity(self.len() * 2); + + self.iter().for_each(|(k, v)| { + res.push((*k).clone().into()); + res.push((*v).clone().into()); + }); + + return res; + } + + fn from_network_map(input: &mut Self::Item) -> Self { + let mut res = HashMap::with_capacity(input.len() / 2); + + input.iter().tuples().for_each(|(k, v)| { + res.insert( + match T::try_from(k.clone()) { + Ok(it) => it, + _ => unreachable!(), + }, + match S::try_from(v.clone()) { + Ok(it) => it, + _ => unreachable!(), + }, + ); + }); + + return res; + } +} + impl Serialize for Variant { fn serialize(&self) -> Result<Vec<u8>, Error> { let unknown: u8 = 0x00; |
