diff options
| author | mat <github@matdoes.dev> | 2022-08-29 21:09:57 -0500 |
|---|---|---|
| committer | mat <github@matdoes.dev> | 2022-08-29 21:09:57 -0500 |
| commit | d9d7b87d6170a4a087f1919d6efa390db6932083 (patch) | |
| tree | 82e42e9aa09106ada008837e9c0de13362c18f47 /azalea-buf/buf-macros/src | |
| parent | d4c8c5a9523d2fd93b013a1c51d50c54d40b090a (diff) | |
| download | azalea-drasl-d9d7b87d6170a4a087f1919d6efa390db6932083.tar.xz | |
buf macros -> azalea-buf-macros
Diffstat (limited to 'azalea-buf/buf-macros/src')
| -rw-r--r-- | azalea-buf/buf-macros/src/lib.rs | 182 |
1 files changed, 0 insertions, 182 deletions
diff --git a/azalea-buf/buf-macros/src/lib.rs b/azalea-buf/buf-macros/src/lib.rs deleted file mode 100644 index 43e60e6e..00000000 --- a/azalea-buf/buf-macros/src/lib.rs +++ /dev/null @@ -1,182 +0,0 @@ -use proc_macro::TokenStream; -use quote::{quote, ToTokens}; -use syn::{self, parse_macro_input, Data, DeriveInput, FieldsNamed, Ident}; - -fn create_impl_mcbufreadable(ident: &Ident, data: &Data) -> proc_macro2::TokenStream { - match data { - syn::Data::Struct(syn::DataStruct { fields, .. }) => { - let FieldsNamed { named, .. } = match fields { - syn::Fields::Named(f) => f, - _ => panic!("#[derive(McBuf)] can only be used on structs with named fields"), - }; - - let read_fields = named - .iter() - .map(|f| { - let field_name = &f.ident; - let field_type = &f.ty; - // do a different buf.write_* for each field depending on the type - // if it's a string, use buf.write_string - match field_type { - syn::Type::Path(_) | syn::Type::Array(_) => { - if f.attrs.iter().any(|a| a.path.is_ident("var")) { - quote! { - let #field_name = azalea_buf::McBufVarReadable::var_read_from(buf)?; - } - } else { - quote! { - let #field_name = azalea_buf::McBufReadable::read_from(buf)?; - } - } - } - _ => panic!( - "Error reading field {}: {}", - field_name.clone().unwrap(), - field_type.to_token_stream() - ), - } - }) - .collect::<Vec<_>>(); - let read_field_names = named.iter().map(|f| &f.ident).collect::<Vec<_>>(); - - quote! { - impl azalea_buf::McBufReadable for #ident { - fn read_from(buf: &mut impl std::io::Read) -> Result<Self, azalea_buf::BufReadError> { - #(#read_fields)* - Ok(#ident { - #(#read_field_names: #read_field_names),* - }) - } - } - } - } - syn::Data::Enum(syn::DataEnum { variants, .. }) => { - let mut match_contents = quote!(); - let mut variant_discrim: u32 = 0; - for variant in variants { - let variant_name = &variant.ident; - match &variant.discriminant.as_ref() { - Some(d) => { - variant_discrim = match &d.1 { - syn::Expr::Lit(e) => match &e.lit { - syn::Lit::Int(i) => i.base10_parse().unwrap(), - _ => panic!("Error parsing enum discriminant as int"), - }, - syn::Expr::Unary(_) => { - panic!("Negative enum discriminants are not supported") - } - _ => { - panic!("Error parsing enum discriminant as literal (is {:?})", d.1) - } - } - } - None => { - variant_discrim += 1; - } - } - match_contents.extend(quote! { - #variant_discrim => Ok(Self::#variant_name), - }); - } - - quote! { - impl azalea_buf::McBufReadable for #ident { - fn read_from(buf: &mut impl std::io::Read) -> Result<Self, azalea_buf::BufReadError> - { - let id = azalea_buf::McBufVarReadable::var_read_from(buf)?; - match id { - #match_contents - _ => Err(azalea_buf::BufReadError::UnexpectedEnumVariant { id: id as i32 }), - } - } - } - } - } - _ => panic!("#[derive(McBuf)] can only be used on structs"), - } -} - -fn create_impl_mcbufwritable(ident: &Ident, data: &Data) -> proc_macro2::TokenStream { - match data { - syn::Data::Struct(syn::DataStruct { fields, .. }) => { - let FieldsNamed { named, .. } = match fields { - syn::Fields::Named(f) => f, - _ => panic!("#[derive(McBuf)] can only be used on structs with named fields"), - }; - - let write_fields = named - .iter() - .map(|f| { - let field_name = &f.ident; - let field_type = &f.ty; - // do a different buf.write_* for each field depending on the type - // if it's a string, use buf.write_string - match field_type { - syn::Type::Path(_) | syn::Type::Array(_) => { - if f.attrs.iter().any(|attr| attr.path.is_ident("var")) { - quote! { - azalea_buf::McBufVarWritable::var_write_into(&self.#field_name, buf)?; - } - } else { - quote! { - azalea_buf::McBufWritable::write_into(&self.#field_name, buf)?; - } - } - } - _ => panic!( - "Error writing field {}: {}", - field_name.clone().unwrap(), - field_type.to_token_stream() - ), - } - }) - .collect::<Vec<_>>(); - - quote! { - impl azalea_buf::McBufWritable for #ident { - fn write_into(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { - #(#write_fields)* - Ok(()) - } - } - } - } - syn::Data::Enum(syn::DataEnum { .. }) => { - quote! { - impl azalea_buf::McBufWritable for #ident { - fn write_into(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { - azalea_buf::Writable::write_varint(buf, *self as i32) - } - } - } - } - _ => panic!("#[derive(McBuf)] can only be used on structs"), - } -} - -#[proc_macro_derive(McBufReadable, attributes(var))] -pub fn derive_mcbufreadable(input: TokenStream) -> TokenStream { - let DeriveInput { ident, data, .. } = parse_macro_input!(input); - - create_impl_mcbufreadable(&ident, &data).into() -} - -#[proc_macro_derive(McBufWritable, attributes(var))] -pub fn derive_mcbufwritable(input: TokenStream) -> TokenStream { - let DeriveInput { ident, data, .. } = parse_macro_input!(input); - - create_impl_mcbufwritable(&ident, &data).into() -} - -#[proc_macro_derive(McBuf, attributes(var))] -pub fn derive_mcbuf(input: TokenStream) -> TokenStream { - let DeriveInput { ident, data, .. } = parse_macro_input!(input); - - let writable = create_impl_mcbufwritable(&ident, &data); - let readable = create_impl_mcbufreadable(&ident, &data); - quote! { - #writable - #readable - } - .into() -} |
