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 /derive/src | |
| parent | adapt Sync* types (diff) | |
migrate to separated NetworkMap and NetworkList macros
Diffstat (limited to '')
| -rw-r--r-- | derive/src/from/mod.rs | 1 | ||||
| -rw-r--r-- | derive/src/network/list.rs | 40 | ||||
| -rw-r--r-- | derive/src/network/map.rs | 73 | ||||
| -rw-r--r-- | derive/src/network/maplist.rs | 54 | ||||
| -rw-r--r-- | derive/src/network/mod.rs | 86 |
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 { |
