aboutsummaryrefslogtreecommitdiff
path: root/derive
diff options
context:
space:
mode:
authorMax Audron <audron@cocaine.farm>2021-10-01 18:13:43 +0200
committerMax Audron <audron@cocaine.farm>2021-10-01 18:17:03 +0200
commit8465010f3cb51d672b60df39a7dfd34624ab5c7c (patch)
tree062d8640f7e7c4aea2a2e4029ea742982ba20911 /derive
parentadapt Sync* types (diff)
migrate to separated NetworkMap and NetworkList macros
Diffstat (limited to 'derive')
-rw-r--r--derive/src/from/mod.rs1
-rw-r--r--derive/src/network/list.rs40
-rw-r--r--derive/src/network/map.rs73
-rw-r--r--derive/src/network/maplist.rs54
-rw-r--r--derive/src/network/mod.rs86
5 files changed, 187 insertions, 67 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 {