diff options
| author | Max Audron <audron@cocaine.farm> | 2023-12-20 13:13:00 +0100 |
|---|---|---|
| committer | Max Audron <audron@cocaine.farm> | 2023-12-20 13:13:00 +0100 |
| commit | e6980211c4c53fc1eeb686cd12363a8fa603daa3 (patch) | |
| tree | 2c248fc32d258dea722dbbefd7ab5465954e2ebc /derive/src/network | |
| parent | use VariantMap as target for generic NetworkMap for HashMap impl (diff) | |
rework Network derives to be more consistent
i don't even know anymore, blame past me
Diffstat (limited to 'derive/src/network')
| -rw-r--r-- | derive/src/network/list.rs | 57 | ||||
| -rw-r--r-- | derive/src/network/map.rs | 109 | ||||
| -rw-r--r-- | derive/src/network/maplist.rs | 75 | ||||
| -rw-r--r-- | derive/src/network/mod.rs | 42 |
4 files changed, 103 insertions, 180 deletions
diff --git a/derive/src/network/list.rs b/derive/src/network/list.rs index 0c6e626..973444e 100644 --- a/derive/src/network/list.rs +++ b/derive/src/network/list.rs @@ -1,7 +1,7 @@ use proc_macro2::TokenStream; use quote::quote; -use super::{get_field_type, get_field_type_colon, get_field_variant_type, NetworkField}; +use super::{get_field_variant_type, NetworkField}; pub(crate) fn to(fields: &Vec<NetworkField>) -> Vec<TokenStream> { fields @@ -16,17 +16,14 @@ pub(crate) fn to(fields: &Vec<NetworkField>) -> Vec<TokenStream> { let field_name = field.ident.as_ref().unwrap(); let field_type = get_field_variant_type(&field); - let field_inner = if field.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() }, - } + let field_inner = match field.network { + crate::network::NetworkRepr::List => { + quote! { libquassel::message::NetworkList::to_network_list(&self.#field_name).into() } } - } else { - quote! { self.#field_name.clone() } + crate::network::NetworkRepr::Map => { + quote! { libquassel::message::NetworkMap::to_network_map(&self.#field_name).into() } + } + crate::network::NetworkRepr::None => quote! { self.#field_name.clone().into() }, }; quote! { @@ -56,49 +53,35 @@ pub(crate) fn from(fields: &Vec<NetworkField>) -> Vec<TokenStream> { None => format!("{}", field.ident.as_ref().unwrap()).into(), }; - let field_type = get_field_type(&field); let field_variant_type = get_field_variant_type(&field); - let field_type_colon = get_field_type_colon(field_type.clone()); - let extract_inner = quote! { let mut i = input.iter(); 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") { - libquassel::primitive::Variant::#field_variant_type(var) => var.clone(), + libquassel::primitive::Variant::#field_variant_type(var) => var.clone().try_into().unwrap(), _ => panic!("network::list::from: wrong variant type"), } }; - if field.network { - if field.map { - quote! { - #field_name: #field_type_colon::from_network_map(&mut { + match field.network { + super::NetworkRepr::List => quote! { + #field_name: libquassel::message::NetworkList::from_network_list(&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! { + }, + super::NetworkRepr::Map => quote! { + #field_name: libquassel::message::NetworkMap::from_network_map(&mut { + #extract_inner + }), + }, + super::NetworkRepr::None => quote! { #field_name: { #extract_inner }, - } + }, } } }) diff --git a/derive/src/network/map.rs b/derive/src/network/map.rs index 5402f5a..0550ccb 100644 --- a/derive/src/network/map.rs +++ b/derive/src/network/map.rs @@ -1,7 +1,7 @@ use proc_macro2::{Ident, TokenStream}; use quote::quote; -use super::{get_field_type, get_field_type_colon, get_field_variant_type, NetworkField}; +use super::{get_field_variant_type, NetworkField}; pub(crate) fn to(fields: &Vec<NetworkField>) -> Vec<TokenStream> { fields @@ -14,28 +14,18 @@ pub(crate) fn to(fields: &Vec<NetworkField>) -> Vec<TokenStream> { }; let field_name = field.ident.as_ref().unwrap(); - let _field_type = get_field_type(&field); let field_variant_type = get_field_variant_type(&field); - let field_inner = if field.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() - } + let field_inner = match field.network { + crate::network::NetworkRepr::List => quote! { + libquassel::message::NetworkList::to_network_list(&self.#field_name).into() + }, + crate::network::NetworkRepr::Map => quote! { + libquassel::message::NetworkMap::to_network_map(&self.#field_name).into() + }, + crate::network::NetworkRepr::None => quote! { + self.#field_name.clone().into() + }, }; quote! { @@ -65,70 +55,37 @@ pub(crate) fn from(fields: &Vec<NetworkField>) -> Vec<TokenStream> { None => format!("{}", field.ident.as_ref().unwrap()).into(), }; - let field_type = get_field_type(&field); - let _field_variant_type = get_field_variant_type(&field); - - let field_type_colon = get_field_type_colon(field_type.clone()); - - if field.network { - 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! { + match field.network { + super::NetworkRepr::List => quote! { + #field_name: libquassel::message::NetworkList::from_network_list( + &mut std::convert::TryInto::try_into(input.remove(#field_rename).unwrap()).unwrap()), + }, + super::NetworkRepr::Map => quote! { + #field_name: libquassel::message::NetworkMap::from_network_map( + &mut std::convert::TryInto::try_into(input.remove(#field_rename).unwrap()).unwrap()), + }, + super::NetworkRepr::None => quote! { #field_name: std::convert::TryInto::try_into(input.remove(#field_rename).unwrap()).unwrap(), - } + }, } } }) .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 to_vec(_type_name: &Ident, _fields: &Vec<NetworkField>) -> TokenStream { + quote! { + self.iter().map(|item| { + item.to_network_map().into() + }).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() - } +pub(crate) fn from_vec(type_name: &Ident, _fields: &Vec<NetworkField>) -> TokenStream { + quote! { + input.iter().map( + |item| #type_name::from_network_map( + &mut std::convert::TryInto::try_into(item).unwrap() + )).collect() } } diff --git a/derive/src/network/maplist.rs b/derive/src/network/maplist.rs index 19877cb..ebda601 100644 --- a/derive/src/network/maplist.rs +++ b/derive/src/network/maplist.rs @@ -1,7 +1,7 @@ use proc_macro2::{Ident, TokenStream}; use quote::quote; -use crate::network::get_field_variant_type; +use crate::network::{get_field_variant_type, gen_type}; use super::NetworkField; @@ -18,14 +18,16 @@ pub(crate) fn to(fields: &Vec<NetworkField>) -> Vec<TokenStream> { let field_name = field.ident.as_ref().unwrap(); let field_type = get_field_variant_type(&field); - let field_inner = if field.network { - quote! { - self.#field_name.to_network().into() - } - } else { - quote! { + let field_inner = match field.network { + crate::network::NetworkRepr::List => quote! { + self.#field_name.to_network_list().into() + }, + crate::network::NetworkRepr::Map => quote! { + self.#field_name.to_network_map().into() + }, + crate::network::NetworkRepr::None => quote! { self.#field_name.clone().into() - } + }, }; if let Some(_) = field.variant { @@ -63,24 +65,27 @@ pub(crate) fn to_vec(_type_name: &Ident, fields: &Vec<NetworkField>) -> TokenStr }; let field_name = field.ident.as_ref().unwrap(); - let field_type = get_field_variant_type(&field); - let field_inner = if field.network { - if field.map { - quote! { - item.#field_name.to_network_map() - } - } else { - quote! { - item.#field_name.to_network() - } - } - } else { - quote! { + let field_type = match field.network { + crate::network::NetworkRepr::List => gen_type("VariantList"), + crate::network::NetworkRepr::Map => gen_type("VariantMap"), + crate::network::NetworkRepr::None => get_field_variant_type(&field), + }; + + let field_inner = match field.network { + crate::network::NetworkRepr::List => quote! { + item.#field_name.to_network_list().into() + }, + crate::network::NetworkRepr::Map => quote! { + item.#field_name.to_network_map().into() + }, + crate::network::NetworkRepr::None => quote! { item.#field_name.clone().into() - } + }, }; + // FIXME this section doesn't make any sense to me anymore + // why do we select a StringList if we have configured a variant??? if let Some(_) = field.variant { lists.push(quote! { let mut #field_name: libquassel::primitive::StringList = Vec::with_capacity(self.len()); @@ -145,14 +150,16 @@ pub(crate) fn from(fields: &Vec<NetworkField>) -> Vec<TokenStream> { let field_type = get_field_variant_type(&field); - let field_inner = if field.network { - quote! { + let field_inner = match field.network { + super::NetworkRepr::List => quote! { libquassel::message::NetworkList::from_network_list(&mut std::convert::TryInto::try_into(input.remove(0)).unwrap()) - } - } else { - quote! { + }, + super::NetworkRepr::Map => quote! { + libquassel::message::NetworkMap::from_network_map(&mut std::convert::TryInto::try_into(input.remove(0)).unwrap()) + }, + super::NetworkRepr::None => quote! { std::convert::TryInto::try_into(input.remove(0)).unwrap() - } + }, }; if let Some(_) = field.variant { @@ -175,7 +182,7 @@ pub(crate) fn from(fields: &Vec<NetworkField>) -> Vec<TokenStream> { .collect() } -pub(crate) fn from_vec(type_name: &Ident, fields: &Vec<NetworkField>, new: bool) -> TokenStream { +pub(crate) fn from_vec(type_name: &Ident, fields: &Vec<NetworkField>) -> TokenStream { let field = &fields[0]; let field_rename = match &field.rename { @@ -196,14 +203,8 @@ pub(crate) fn from_vec(type_name: &Ident, fields: &Vec<NetworkField>, new: bool) }, }; - let inner = if new { - quote! { - #type_name::from_network_map(input) - } - } else { - quote! { - #type_name::from_network_list(input) - } + let inner = quote! { + #type_name::from_network_map(input) }; quote! { diff --git a/derive/src/network/mod.rs b/derive/src/network/mod.rs index 2d4c89d..aea8080 100644 --- a/derive/src/network/mod.rs +++ b/derive/src/network/mod.rs @@ -20,17 +20,20 @@ pub struct Network { /// List: /// Map: /// Maplist: -#[derive(Debug, Clone, Copy, PartialEq, FromMeta)] +#[derive(Debug, Default, Clone, Copy, PartialEq, FromMeta)] pub enum Repr { List, + #[default] Map, Maplist, } -impl Default for Repr { - fn default() -> Self { - Repr::Map - } +#[derive(Debug, Default, Clone, Copy, PartialEq, FromMeta)] +pub enum NetworkRepr { + List, + Map, + #[default] + None, } #[derive(Debug, FromField)] @@ -50,11 +53,7 @@ pub struct NetworkField { /// field is a nested network repr so /// 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, + network: NetworkRepr, /// Skips this field when parsing from network /// representation and uses the default value of the type #[darling(default)] @@ -135,13 +134,13 @@ pub fn network_map(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let to_network_map_vec = match network.repr { Repr::Maplist => maplist::to_vec(name, &fields), - Repr::Map => map::to_vec(name, &fields, true), + Repr::Map => map::to_vec(name, &fields), _ => 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), + Repr::Maplist => maplist::from_vec(name, &fields), + Repr::Map => map::from_vec(name, &fields), _ => unimplemented!(), }; @@ -241,20 +240,3 @@ fn gen_type(typ: &str) -> syn::Type { }, }) } - -fn get_field_type_colon(mut ty: syn::Type) -> syn::Type { - match &mut ty { - syn::Type::Path(path) => { - let first_seg = path.path.segments.first_mut().unwrap(); - match &mut first_seg.arguments { - syn::PathArguments::AngleBracketed(bracket) => { - bracket.colon2_token = Some(syn::parse_str("::").unwrap()); - } - _ => (), - } - } - _ => (), - }; - - return ty; -} |
