From: Lizzy Fleckenstein Date: Mon, 13 Feb 2023 16:02:53 +0000 (+0100) Subject: cargo fmt X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=917df4d688fd9c91ca02acaced8f7de35124a5e3;p=mt_ser.git cargo fmt --- diff --git a/derive/src/lib.rs b/derive/src/lib.rs index 52de2f2..f6cd69b 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -7,400 +7,401 @@ use syn::{parse_macro_input, parse_quote}; #[derive(Debug, FromMeta, Copy, Clone, Eq, PartialEq)] #[darling(rename_all = "snake_case")] enum To { - Clt, - Srv, + Clt, + Srv, } #[derive(Debug, FromMeta)] struct MacroArgs { - to: To, - repr: Option, - tag: Option, - content: Option, - #[darling(default)] - custom: bool, - #[darling(default)] - enumset: bool, + to: To, + repr: Option, + tag: Option, + content: Option, + #[darling(default)] + custom: bool, + #[darling(default)] + enumset: bool, } fn wrap_attr(attr: &mut syn::Attribute) { - let path = attr.path.clone(); - let tokens = attr.tokens.clone(); - - match attr.path.get_ident().map(|i| i.to_string()).as_deref() { - Some("mt") => { - *attr = parse_quote! { - #[cfg_attr(any(feature = "client", feature = "server"), #path #tokens)] - }; - } - Some("serde") => { - *attr = parse_quote! { - #[cfg_attr(feature = "serde", #path #tokens)] - }; - } - _ => {} - } + let path = attr.path.clone(); + let tokens = attr.tokens.clone(); + + match attr.path.get_ident().map(|i| i.to_string()).as_deref() { + Some("mt") => { + *attr = parse_quote! { + #[cfg_attr(any(feature = "client", feature = "server"), #path #tokens)] + }; + } + Some("serde") => { + *attr = parse_quote! { + #[cfg_attr(feature = "serde", #path #tokens)] + }; + } + _ => {} + } } #[proc_macro_attribute] pub fn mt_derive(attr: TokenStream, item: TokenStream) -> TokenStream { - let item2 = item.clone(); - - let attr_args = parse_macro_input!(attr as syn::AttributeArgs); - let mut input = parse_macro_input!(item2 as syn::Item); - - let args = match MacroArgs::from_list(&attr_args) { - Ok(v) => v, - Err(e) => { - return TokenStream::from(e.write_errors()); - } - }; - - let (serializer, deserializer) = match args.to { - To::Clt => ("server", "client"), - To::Srv => ("client", "server"), - }; - - let mut out = quote! { - #[derive(Debug)] - #[cfg_attr(feature = "random", derive(GenerateRandom))] - #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] - }; - - macro_rules! iter { - ($t:expr, $f:expr) => { - $t.iter_mut().for_each($f) - }; - } - - match &mut input { - syn::Item::Enum(e) => { - iter!(e.attrs, wrap_attr); - iter!(e.variants, |v| { - iter!(v.attrs, wrap_attr); - iter!(v.fields, |f| iter!(f.attrs, wrap_attr)); - }); - - let repr = args.repr.expect("missing repr for enum"); - - if args.enumset { - let repr_str = repr.to_token_stream().to_string(); - - out.extend(quote! { - #[derive(EnumSetType)] - #[enumset(repr = #repr_str, serialize_as_map)] - }) - } else { - let has_payload = e - .variants - .iter() - .find_map(|v| if v.fields.is_empty() { None } else { Some(()) }) - .is_some(); - - if has_payload { - let tag = args.tag.expect("missing tag for enum with payload"); - - out.extend(quote! { - #[cfg_attr(feature = "serde", serde(tag = #tag))] - }); - - if let Some(content) = args.content { - out.extend(quote! { - #[cfg_attr(feature = "serde", serde(content = #content))] - }); - } - } else { - out.extend(quote! { - #[derive(Copy, Eq)] - }); - } - - out.extend(quote! { - #[repr(#repr)] - #[derive(Clone, PartialEq)] - }); - - if !args.custom { - out.extend(quote! { - #[cfg_attr(feature = #serializer, derive(MtSerialize))] - #[cfg_attr(feature = #deserializer, derive(MtDeserialize))] - }); - } - } - - out.extend(quote! { - #[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))] - }); - } - syn::Item::Struct(s) => { - iter!(s.attrs, wrap_attr); - iter!(s.fields, |f| iter!(f.attrs, wrap_attr)); - - out.extend(quote! { - #[derive(Clone, PartialEq)] - }); - - if !args.custom { - out.extend(quote! { - #[cfg_attr(feature = #serializer, derive(MtSerialize))] - #[cfg_attr(feature = #deserializer, derive(MtDeserialize))] - }); - } - } - _ => panic!("only enum and struct supported"), - } - - out.extend(input.to_token_stream()); - out.into() + let item2 = item.clone(); + + let attr_args = parse_macro_input!(attr as syn::AttributeArgs); + let mut input = parse_macro_input!(item2 as syn::Item); + + let args = match MacroArgs::from_list(&attr_args) { + Ok(v) => v, + Err(e) => { + return TokenStream::from(e.write_errors()); + } + }; + + let (serializer, deserializer) = match args.to { + To::Clt => ("server", "client"), + To::Srv => ("client", "server"), + }; + + let mut out = quote! { + #[derive(Debug)] + #[cfg_attr(feature = "random", derive(GenerateRandom))] + #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] + }; + + macro_rules! iter { + ($t:expr, $f:expr) => { + $t.iter_mut().for_each($f) + }; + } + + match &mut input { + syn::Item::Enum(e) => { + iter!(e.attrs, wrap_attr); + iter!(e.variants, |v| { + iter!(v.attrs, wrap_attr); + iter!(v.fields, |f| iter!(f.attrs, wrap_attr)); + }); + + let repr = args.repr.expect("missing repr for enum"); + + if args.enumset { + let repr_str = repr.to_token_stream().to_string(); + + out.extend(quote! { + #[derive(EnumSetType)] + #[enumset(repr = #repr_str, serialize_as_map)] + }) + } else { + let has_payload = e + .variants + .iter() + .find_map(|v| if v.fields.is_empty() { None } else { Some(()) }) + .is_some(); + + if has_payload { + let tag = args.tag.expect("missing tag for enum with payload"); + + out.extend(quote! { + #[cfg_attr(feature = "serde", serde(tag = #tag))] + }); + + if let Some(content) = args.content { + out.extend(quote! { + #[cfg_attr(feature = "serde", serde(content = #content))] + }); + } + } else { + out.extend(quote! { + #[derive(Copy, Eq)] + }); + } + + out.extend(quote! { + #[repr(#repr)] + #[derive(Clone, PartialEq)] + }); + + if !args.custom { + out.extend(quote! { + #[cfg_attr(feature = #serializer, derive(MtSerialize))] + #[cfg_attr(feature = #deserializer, derive(MtDeserialize))] + }); + } + } + + out.extend(quote! { + #[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))] + }); + } + syn::Item::Struct(s) => { + iter!(s.attrs, wrap_attr); + iter!(s.fields, |f| iter!(f.attrs, wrap_attr)); + + out.extend(quote! { + #[derive(Clone, PartialEq)] + }); + + if !args.custom { + out.extend(quote! { + #[cfg_attr(feature = #serializer, derive(MtSerialize))] + #[cfg_attr(feature = #deserializer, derive(MtDeserialize))] + }); + } + } + _ => panic!("only enum and struct supported"), + } + + out.extend(input.to_token_stream()); + out.into() } #[derive(Debug, Default, FromDeriveInput, FromVariant, FromField)] #[darling(attributes(mt))] #[darling(default)] struct MtArgs { - #[darling(multiple)] - const_before: Vec, // must implement MtSerialize + MtDeserialize + PartialEq + #[darling(multiple)] + const_before: Vec, // must implement MtSerialize + MtDeserialize + PartialEq - #[darling(multiple)] - const_after: Vec, // must implement MtSerialize + MtDeserialize + PartialEq + #[darling(multiple)] + const_after: Vec, // must implement MtSerialize + MtDeserialize + PartialEq - size: Option, // must implement MtCfg + size: Option, // must implement MtCfg - len: Option, // must implement MtCfg + len: Option, // must implement MtCfg - zlib: bool, - zstd: bool, // TODO - default: bool, // type must implement Default + zlib: bool, + zstd: bool, // TODO + default: bool, // type must implement Default } type Fields<'a> = Vec<(TokStr, &'a syn::Field)>; fn get_fields(fields: &syn::Fields, ident: impl Fn(TokStr) -> TokStr) -> Fields { - match fields { - syn::Fields::Named(fs) => fs - .named - .iter() - .map(|f| (ident(f.ident.as_ref().unwrap().to_token_stream()), f)) - .collect(), - syn::Fields::Unnamed(fs) => fs - .unnamed - .iter() - .enumerate() - .map(|(i, f)| (ident(syn::Index::from(i).to_token_stream()), f)) - .collect(), - syn::Fields::Unit => Vec::new(), - } + match fields { + syn::Fields::Named(fs) => fs + .named + .iter() + .map(|f| (ident(f.ident.as_ref().unwrap().to_token_stream()), f)) + .collect(), + syn::Fields::Unnamed(fs) => fs + .unnamed + .iter() + .enumerate() + .map(|(i, f)| (ident(syn::Index::from(i).to_token_stream()), f)) + .collect(), + syn::Fields::Unit => Vec::new(), + } } fn serialize_args(res: darling::Result, body: impl FnOnce(&MtArgs) -> TokStr) -> TokStr { - match res { - Ok(args) => { - let mut code = body(&args); - - if args.zlib { - code = quote! { - let mut __writer = { - let mut __stream = mt_ser::flate2::write::ZlibEncoder::new( - __writer, - mt_ser::flate2::Compression::default(), - ); - let __writer = &mut __stream; - #code - __stream.finish()? - }; - }; - } - - if let Some(size) = args.size { - code = quote! { - mt_ser::MtSerialize::mt_serialize::<#size>(&{ - let mut __buf = Vec::new(); - let __writer = &mut __buf; - #code - __buf - }, __writer)?; - }; - } - - for x in args.const_before.iter().rev() { - code = quote! { - #x.mt_serialize::(__writer)?; - #code - } - } - - for x in args.const_after.iter() { - code = quote! { - #code - #x.mt_serialize::(__writer)?; - } - } - - code - } - Err(e) => return e.write_errors(), - } + match res { + Ok(args) => { + let mut code = body(&args); + + if args.zlib { + code = quote! { + let mut __writer = { + let mut __stream = mt_ser::flate2::write::ZlibEncoder::new( + __writer, + mt_ser::flate2::Compression::default(), + ); + let __writer = &mut __stream; + #code + __stream.finish()? + }; + }; + } + + if let Some(size) = args.size { + code = quote! { + mt_ser::MtSerialize::mt_serialize::<#size>(&{ + let mut __buf = Vec::new(); + let __writer = &mut __buf; + #code + __buf + }, __writer)?; + }; + } + + for x in args.const_before.iter().rev() { + code = quote! { + #x.mt_serialize::(__writer)?; + #code + } + } + + for x in args.const_after.iter() { + code = quote! { + #code + #x.mt_serialize::(__writer)?; + } + } + + code + } + Err(e) => return e.write_errors(), + } } fn deserialize_args(res: darling::Result, body: impl FnOnce(&MtArgs) -> TokStr) -> TokStr { - match res { - Ok(args) => { - let mut code = body(&args); - - if args.zlib { - code = quote! { - { - let mut __owned_reader = mt_ser::flate2::read::ZlibDecoder::new( - mt_ser::WrapRead(__reader)); - let __reader = &mut __owned_reader; - - #code - } - } - } - - - if let Some(size) = args.size { - code = quote! { - #size::mt_deserialize::(__reader).and_then(|size| { - let mut __owned_reader = std::io::Read::take( - mt_ser::WrapRead(__reader), size as u64); - let __reader = &mut __owned_reader; - - #code - }) - }; - } - - let impl_const = |value: TokStr| quote! { - { - fn deserialize_same_type( - _: &T, - reader: &mut impl std::io::Read - ) -> Result { - T::mt_deserialize::(reader) - } - - deserialize_same_type(&want, __reader) - .and_then(|got| { - if want == got { - #value - } else { - Err(mt_ser::DeserializeError::InvalidConst( - Box::new(want), Box::new(got) - )) - } - }) - } - }; - - for want in args.const_before.iter().rev() { - let imp = impl_const(code); - code = quote! { - { - let want = #want; - #imp - } - }; - } - - for want in args.const_after.iter() { - let imp = impl_const(quote! { Ok(value) }); - code = quote! { - { - let want = #want; - #code.and_then(|value| { #imp }) - } - }; - } - - code - } - Err(e) => return e.write_errors(), - } + match res { + Ok(args) => { + let mut code = body(&args); + + if args.zlib { + code = quote! { + { + let mut __owned_reader = mt_ser::flate2::read::ZlibDecoder::new( + mt_ser::WrapRead(__reader)); + let __reader = &mut __owned_reader; + + #code + } + } + } + + if let Some(size) = args.size { + code = quote! { + #size::mt_deserialize::(__reader).and_then(|size| { + let mut __owned_reader = std::io::Read::take( + mt_ser::WrapRead(__reader), size as u64); + let __reader = &mut __owned_reader; + + #code + }) + }; + } + + let impl_const = |value: TokStr| { + quote! { + { + fn deserialize_same_type( + _: &T, + reader: &mut impl std::io::Read + ) -> Result { + T::mt_deserialize::(reader) + } + + deserialize_same_type(&want, __reader) + .and_then(|got| { + if want == got { + #value + } else { + Err(mt_ser::DeserializeError::InvalidConst( + Box::new(want), Box::new(got) + )) + } + }) + } + } + }; + + for want in args.const_before.iter().rev() { + let imp = impl_const(code); + code = quote! { + { + let want = #want; + #imp + } + }; + } + + for want in args.const_after.iter() { + let imp = impl_const(quote! { Ok(value) }); + code = quote! { + { + let want = #want; + #code.and_then(|value| { #imp }) + } + }; + } + + code + } + Err(e) => return e.write_errors(), + } } fn serialize_fields(fields: &Fields) -> TokStr { - fields - .iter() - .map(|(ident, field)| { - serialize_args(MtArgs::from_field(field), |args| { - let def = parse_quote! { mt_ser::DefCfg }; - let len = args.len.as_ref().unwrap_or(&def); - quote! { mt_ser::MtSerialize::mt_serialize::<#len>(#ident, __writer)?; } - }) - }) - .collect() + fields + .iter() + .map(|(ident, field)| { + serialize_args(MtArgs::from_field(field), |args| { + let def = parse_quote! { mt_ser::DefCfg }; + let len = args.len.as_ref().unwrap_or(&def); + quote! { mt_ser::MtSerialize::mt_serialize::<#len>(#ident, __writer)?; } + }) + }) + .collect() } fn deserialize_fields(fields: &Fields) -> TokStr { - fields - .iter() - .map(|(ident, field)| { - let code = deserialize_args(MtArgs::from_field(field), |args| { - let def = parse_quote! { mt_ser::DefCfg }; - let len = args.len.as_ref().unwrap_or(&def); - let mut code = quote! { mt_ser::MtDeserialize::mt_deserialize::<#len>(__reader) }; - - if args.default { - code = quote! { - mt_ser::OrDefault::or_default(#code) - }; - } - - code - }); - - quote! { - let #ident = #code?; - } - }) - .collect() + fields + .iter() + .map(|(ident, field)| { + let code = deserialize_args(MtArgs::from_field(field), |args| { + let def = parse_quote! { mt_ser::DefCfg }; + let len = args.len.as_ref().unwrap_or(&def); + let mut code = quote! { mt_ser::MtDeserialize::mt_deserialize::<#len>(__reader) }; + + if args.default { + code = quote! { + mt_ser::OrDefault::or_default(#code) + }; + } + + code + }); + + quote! { + let #ident = #code?; + } + }) + .collect() } fn get_fields_struct(input: &syn::Fields) -> (Fields, TokStr) { - let ident_fn = match input { - syn::Fields::Unnamed(_) => |f| { - quote! { - mt_ser::paste::paste! { [] } - } - }, - _ => |f| quote! { #f }, - }; - - let fields = get_fields(input, ident_fn); - let fields_comma: TokStr = fields - .iter() - .rfold(TokStr::new(), |after, (ident, _)| quote! { #ident, #after }); - - let fields_struct = match input { - syn::Fields::Named(_) => quote! { { #fields_comma } }, - syn::Fields::Unnamed(_) => quote! { ( #fields_comma ) }, - syn::Fields::Unit => TokStr::new(), - }; - - (fields, fields_struct) + let ident_fn = match input { + syn::Fields::Unnamed(_) => |f| { + quote! { + mt_ser::paste::paste! { [] } + } + }, + _ => |f| quote! { #f }, + }; + + let fields = get_fields(input, ident_fn); + let fields_comma: TokStr = fields + .iter() + .rfold(TokStr::new(), |after, (ident, _)| quote! { #ident, #after }); + + let fields_struct = match input { + syn::Fields::Named(_) => quote! { { #fields_comma } }, + syn::Fields::Unnamed(_) => quote! { ( #fields_comma ) }, + syn::Fields::Unit => TokStr::new(), + }; + + (fields, fields_struct) } fn get_repr(input: &syn::DeriveInput) -> syn::Type { - input - .attrs - .iter() - .find(|a| a.path.is_ident("repr")) - .expect("missing repr") - .parse_args() - .expect("invalid repr") + input + .attrs + .iter() + .find(|a| a.path.is_ident("repr")) + .expect("missing repr") + .parse_args() + .expect("invalid repr") } #[proc_macro_derive(MtSerialize, attributes(mt))] pub fn derive_serialize(input: TokenStream) -> TokenStream { - let input = parse_macro_input!(input as syn::DeriveInput); - let typename = &input.ident; + let input = parse_macro_input!(input as syn::DeriveInput); + let typename = &input.ident; - let code = serialize_args(MtArgs::from_derive_input(&input), |_| match &input.data { - syn::Data::Enum(e) => { - let repr = get_repr(&input); - let variants: TokStr = e.variants + let code = serialize_args(MtArgs::from_derive_input(&input), |_| match &input.data { + syn::Data::Enum(e) => { + let repr = get_repr(&input); + let variants: TokStr = e.variants .iter() .fold((parse_quote! { 0 }, TokStr::new()), |(discr, before), v| { let discr = v.discriminant.clone().map(|x| x.1).unwrap_or(discr); @@ -422,19 +423,19 @@ pub fn derive_serialize(input: TokenStream) -> TokenStream { ) }).1; - quote! { - match self { - #variants - } - } - } - syn::Data::Struct(s) => serialize_fields(&get_fields(&s.fields, |f| quote! { &self.#f })), - _ => { - panic!("only enum and struct supported"); - } - }); - - quote! { + quote! { + match self { + #variants + } + } + } + syn::Data::Struct(s) => serialize_fields(&get_fields(&s.fields, |f| quote! { &self.#f })), + _ => { + panic!("only enum and struct supported"); + } + }); + + quote! { #[automatically_derived] impl mt_ser::MtSerialize for #typename { fn mt_serialize(&self, __writer: &mut impl std::io::Write) -> Result<(), mt_ser::SerializeError> { @@ -448,67 +449,67 @@ pub fn derive_serialize(input: TokenStream) -> TokenStream { #[proc_macro_derive(MtDeserialize, attributes(mt))] pub fn derive_deserialize(input: TokenStream) -> TokenStream { - let input = parse_macro_input!(input as syn::DeriveInput); - let typename = &input.ident; - - let code = deserialize_args(MtArgs::from_derive_input(&input), |_| match &input.data { - syn::Data::Enum(e) => { - let repr = get_repr(&input); - let type_str = typename.to_string(); - - let mut consts = TokStr::new(); - let mut arms = TokStr::new(); - let mut discr = parse_quote! { 0 }; - - for v in e.variants.iter() { - discr = v.discriminant.clone().map(|x| x.1).unwrap_or(discr); - - let ident = &v.ident; - let (fields, fields_struct) = get_fields_struct(&v.fields); - let code = deserialize_args(MtArgs::from_variant(v), |_| { - let fields_code = deserialize_fields(&fields); - - quote! { - #fields_code - Ok(Self::#ident #fields_struct) - } - }); - - consts.extend(quote! { - const #ident: #repr = #discr; - }); - - arms.extend(quote! { - #ident => { #code } - }); - - discr = parse_quote! { 1 + #discr }; - } - - quote! { - #consts - - match mt_ser::MtDeserialize::mt_deserialize::(__reader)? { - #arms - x => Err(mt_ser::DeserializeError::InvalidEnumVariant(#type_str, x as u64)) - } - } - } - syn::Data::Struct(s) => { - let (fields, fields_struct) = get_fields_struct(&s.fields); - let code = deserialize_fields(&fields); - - quote! { - #code - Ok(Self #fields_struct) - } - } - _ => { - panic!("only enum and struct supported"); - } - }); - - quote! { + let input = parse_macro_input!(input as syn::DeriveInput); + let typename = &input.ident; + + let code = deserialize_args(MtArgs::from_derive_input(&input), |_| match &input.data { + syn::Data::Enum(e) => { + let repr = get_repr(&input); + let type_str = typename.to_string(); + + let mut consts = TokStr::new(); + let mut arms = TokStr::new(); + let mut discr = parse_quote! { 0 }; + + for v in e.variants.iter() { + discr = v.discriminant.clone().map(|x| x.1).unwrap_or(discr); + + let ident = &v.ident; + let (fields, fields_struct) = get_fields_struct(&v.fields); + let code = deserialize_args(MtArgs::from_variant(v), |_| { + let fields_code = deserialize_fields(&fields); + + quote! { + #fields_code + Ok(Self::#ident #fields_struct) + } + }); + + consts.extend(quote! { + const #ident: #repr = #discr; + }); + + arms.extend(quote! { + #ident => { #code } + }); + + discr = parse_quote! { 1 + #discr }; + } + + quote! { + #consts + + match mt_ser::MtDeserialize::mt_deserialize::(__reader)? { + #arms + x => Err(mt_ser::DeserializeError::InvalidEnumVariant(#type_str, x as u64)) + } + } + } + syn::Data::Struct(s) => { + let (fields, fields_struct) = get_fields_struct(&s.fields); + let code = deserialize_fields(&fields); + + quote! { + #code + Ok(Self #fields_struct) + } + } + _ => { + panic!("only enum and struct supported"); + } + }); + + quote! { #[automatically_derived] impl mt_ser::MtDeserialize for #typename { #[allow(non_upper_case_globals)]