1extern crate proc_macro;
2
3use crc::{Crc, CRC_64_ECMA_182};
4use itertools::izip;
5use proc_macro::TokenStream;
6use proc_macro2::Span;
7use quote::quote;
8use std::collections::{HashMap, HashSet};
9use syn::{
10 parse_macro_input, Attribute, Data, DeriveInput, Fields, GenericArgument, Ident, PathArguments,
11 Type,
12};
13
14const CRC64: Crc<u64> = Crc::<u64>::new(&CRC_64_ECMA_182);
16
17fn calculate_id_from_name(name: &str) -> u64 {
31 let crc64_hash = CRC64.checksum(name.as_bytes());
32 if crc64_hash == 0 {
34 u64::MAX
35 } else {
36 crc64_hash
37 }
38}
39
40#[derive(Debug, Clone)]
54#[allow(dead_code)] struct FieldAttributes {
56 id: u64,
57 default: bool,
58 skip_encode: bool,
59 skip_decode: bool,
60 skip_default: bool,
61 rename: Option<String>,
62}
63
64fn get_field_attributes(attrs: &[Attribute], field_name: &str) -> FieldAttributes {
90 let mut id = None;
91 let mut default = false;
92 let mut skip_encode = false;
93 let mut skip_decode = false;
94 let mut skip_default = false;
95 let mut rename = None;
96
97 for attr in attrs {
98 if attr.path().is_ident("senax") {
99 let parsed = attr.parse_args_with(|input: syn::parse::ParseStream| {
101 let mut parsed_id = None;
102 let mut parsed_default = false;
103 let mut parsed_skip_encode = false;
104 let mut parsed_skip_decode = false;
105 let mut parsed_skip_default = false;
106 let mut parsed_rename = None;
107
108 while !input.is_empty() {
109 let ident = input.parse::<syn::Ident>()?;
110
111 if ident == "id" {
112 input.parse::<syn::Token![=]>()?;
113 let lit = input.parse::<syn::LitInt>()?;
114 if let Ok(id_val) = lit.base10_parse::<u64>() {
115 if id_val == 0 {
116 return Err(syn::Error::new(
117 lit.span(),
118 "Field ID 0 is reserved as a terminator",
119 ));
120 }
121 parsed_id = Some(id_val);
122 } else {
123 return Err(syn::Error::new(lit.span(), "Failed to parse ID value"));
124 }
125 } else if ident == "default" {
126 parsed_default = true;
127 } else if ident == "skip_encode" {
128 parsed_skip_encode = true;
129 } else if ident == "skip_decode" {
130 parsed_skip_decode = true;
131 } else if ident == "skip_default" {
132 parsed_skip_default = true;
133 } else if ident == "rename" {
134 input.parse::<syn::Token![=]>()?;
135 let lit_str = input.parse::<syn::LitStr>()?;
136 parsed_rename = Some(lit_str.value());
137 } else {
138 return Err(syn::Error::new(
139 ident.span(),
140 format!("Unknown attribute: {}", ident),
141 ));
142 }
143
144 if input.peek(syn::Token![,]) {
146 input.parse::<syn::Token![,]>()?;
147 }
148 }
149
150 Ok((
151 parsed_id,
152 parsed_default,
153 parsed_skip_encode,
154 parsed_skip_decode,
155 parsed_skip_default,
156 parsed_rename,
157 ))
158 });
159
160 if let Ok((
161 parsed_id,
162 parsed_default,
163 parsed_skip_encode,
164 parsed_skip_decode,
165 parsed_skip_default,
166 parsed_rename,
167 )) = parsed
168 {
169 if let Some(id_val) = parsed_id {
170 id = Some(id_val);
171 }
172 default = default || parsed_default;
173 skip_encode = skip_encode || parsed_skip_encode;
174 skip_decode = skip_decode || parsed_skip_decode;
175 skip_default = skip_default || parsed_skip_default;
176 if let Some(rename_val) = parsed_rename {
177 rename = Some(rename_val);
178 }
179 } else {
180 eprintln!(
181 "Warning: #[senax(...)] attribute for field '{}' is not in the correct format.",
182 field_name
183 );
184 }
185 }
186 }
187
188 let calculated_id = id.unwrap_or_else(|| {
190 let name_for_id = if let Some(ref rename_val) = rename {
191 rename_val.as_str()
192 } else {
193 field_name
194 };
195 calculate_id_from_name(name_for_id)
196 });
197
198 FieldAttributes {
199 id: calculated_id,
200 default,
201 skip_encode,
202 skip_decode,
203 skip_default,
204 rename,
205 }
206}
207
208fn is_option_type(ty: &Type) -> bool {
212 if let Type::Path(type_path) = ty {
213 type_path
214 .path
215 .segments
216 .last()
217 .map_or(false, |seg| seg.ident == "Option")
218 } else {
219 false
220 }
221}
222
223fn extract_inner_type_from_option(ty: &Type) -> Option<&Type> {
228 if let Type::Path(type_path) = ty {
229 if type_path
230 .path
231 .segments
232 .last()
233 .map_or(false, |seg| seg.ident == "Option")
234 {
235 if let PathArguments::AngleBracketed(args) =
236 &type_path.path.segments.last().unwrap().arguments
237 {
238 if let Some(GenericArgument::Type(inner_ty)) = args.args.first() {
239 return Some(inner_ty);
240 }
241 }
242 }
243 }
244 None
245}
246
247#[proc_macro_derive(Encode, attributes(senax))]
271pub fn derive_encode(input: TokenStream) -> TokenStream {
272 let input = parse_macro_input!(input as DeriveInput);
273 let name = &input.ident;
274 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
275
276 let encode_fields = match &input.data {
277 Data::Struct(s) => match &s.fields {
278 Fields::Named(fields) => {
279 let mut field_encode = Vec::new();
280 let mut used_ids_struct = HashSet::new();
281 for f in &fields.named {
282 let field_name_str = f.ident.as_ref().unwrap().to_string();
283 let field_attrs = get_field_attributes(&f.attrs, &field_name_str);
284
285 if field_attrs.skip_encode {
287 continue;
288 }
289
290 if !used_ids_struct.insert(field_attrs.id) {
291 panic!("Field ID (0x{:016X}) is duplicated for struct '{}'. Please specify a different ID for field '{}' using #[senax(id=...)].", field_attrs.id, name, field_name_str);
292 }
293
294 let field_ident = &f.ident;
295 let ty = &f.ty;
296 let is_option = is_option_type(ty);
297 let field_id = field_attrs.id;
298
299 if is_option {
300 field_encode.push(quote! {
301 if let Some(val) = &self.#field_ident {
302 senax_encoder::write_field_id_optimized(writer, #field_id)?;
303 val.encode(writer)?;
304 }
305 });
306 } else if field_attrs.skip_default {
307 field_encode.push(quote! {
309 if !self.#field_ident.is_default() {
310 senax_encoder::write_field_id_optimized(writer, #field_id)?;
311 self.#field_ident.encode(writer)?;
312 }
313 });
314 } else {
315 field_encode.push(quote! {
316 senax_encoder::write_field_id_optimized(writer, #field_id)?;
317 self.#field_ident.encode(writer)?;
318 });
319 }
320 }
321 quote! {
322 writer.put_u8(senax_encoder::TAG_STRUCT_NAMED);
323 #(#field_encode)*
324 senax_encoder::write_field_id_optimized(writer, 0)?;
325 }
326 }
327 Fields::Unnamed(fields) => {
328 let field_count = fields.unnamed.len();
329 let field_encode = fields.unnamed.iter().enumerate().map(|(i, _)| {
330 let index = syn::Index::from(i);
331 quote! {
332 self.#index.encode(writer)?;
333 }
334 });
335 quote! {
336 writer.put_u8(senax_encoder::TAG_STRUCT_UNNAMED);
337 let count: usize = #field_count;
338 count.encode(writer)?;
339 #(#field_encode)*
340 }
341 }
342 Fields::Unit => quote! {
343 writer.put_u8(senax_encoder::TAG_STRUCT_UNIT);
344 },
345 },
346 Data::Enum(e) => {
347 let mut variant_encode = Vec::new();
348 let mut used_ids_enum = HashSet::new();
349
350 for v in &e.variants {
351 let variant_name_str = v.ident.to_string();
352 let variant_attrs = get_field_attributes(&v.attrs, &variant_name_str);
353 let variant_id = variant_attrs.id;
354
355 if !used_ids_enum.insert(variant_id) {
356 panic!("Variant ID (0x{:016X}) is duplicated for enum '{}'. Please specify a different ID for variant '{}' using #[senax(id=...)].", variant_id, name, variant_name_str);
357 }
358
359 let variant_ident = &v.ident;
360 match &v.fields {
361 Fields::Named(fields) => {
362 let field_idents: Vec<_> = fields
363 .named
364 .iter()
365 .map(|f| f.ident.as_ref().unwrap())
366 .collect();
367 let mut field_encode = Vec::new();
368 let mut used_ids_struct = HashSet::new();
369 for f in &fields.named {
370 let field_name_str = f.ident.as_ref().unwrap().to_string();
371 let field_attrs = get_field_attributes(&f.attrs, &field_name_str);
372
373 if field_attrs.skip_encode {
375 continue;
376 }
377
378 if !used_ids_struct.insert(field_attrs.id) {
379 panic!("Field ID (0x{:016X}) is duplicated for enum variant '{}'. Please specify a different ID for field '{}' using #[senax(id=...)].", field_attrs.id, variant_ident, field_name_str);
380 }
381 let field_ident = &f.ident;
382 let ty = &f.ty;
383 let is_option = is_option_type(ty);
384 let field_id = field_attrs.id;
385 if is_option {
386 field_encode.push(quote! {
387 if let Some(val) = #field_ident {
388 senax_encoder::write_field_id_optimized(writer, #field_id)?;
389 val.encode(writer)?;
390 }
391 });
392 } else if field_attrs.skip_default {
393 field_encode.push(quote! {
395 if !#field_ident.is_default() {
396 senax_encoder::write_field_id_optimized(writer, #field_id)?;
397 #field_ident.encode(writer)?;
398 }
399 });
400 } else {
401 field_encode.push(quote! {
402 senax_encoder::write_field_id_optimized(writer, #field_id)?;
403 #field_ident.encode(writer)?;
404 });
405 }
406 }
407 variant_encode.push(quote! {
408 #name::#variant_ident { #(#field_idents),* } => {
409 writer.put_u8(senax_encoder::TAG_ENUM_NAMED);
410 senax_encoder::write_field_id_optimized(writer, #variant_id)?;
411 #(#field_encode)*
412 senax_encoder::write_field_id_optimized(writer, 0)?;
413 }
414 });
415 }
416 Fields::Unnamed(fields) => {
417 let field_count = fields.unnamed.len();
418 let field_bindings: Vec<_> = (0..field_count)
419 .map(|i| Ident::new(&format!("field{}", i), Span::call_site()))
420 .collect();
421 let field_bindings_ref = &field_bindings;
422 variant_encode.push(quote! {
423 #name::#variant_ident( #(#field_bindings_ref),* ) => {
424 writer.put_u8(senax_encoder::TAG_ENUM_UNNAMED);
425 senax_encoder::write_field_id_optimized(writer, #variant_id)?;
426 let count: usize = #field_count;
427 count.encode(writer)?;
428 #(
429 #field_bindings_ref.encode(writer)?;
430 )*
431 }
432 });
433 }
434 Fields::Unit => {
435 variant_encode.push(quote! {
436 #name::#variant_ident => {
437 writer.put_u8(senax_encoder::TAG_ENUM);
438 senax_encoder::write_field_id_optimized(writer, #variant_id)?;
439 }
440 });
441 }
442 }
443 }
444 quote! {
445 match self {
446 #(#variant_encode)*
447 }
448 }
449 }
450 Data::Union(_) => unimplemented!("Unions are not supported"),
451 };
452
453 TokenStream::from(quote! {
454 impl #impl_generics senax_encoder::Encoder for #name #ty_generics #where_clause {
455 fn encode(&self, writer: &mut bytes::BytesMut) -> senax_encoder::Result<()> {
456 use bytes::{Buf, BufMut};
457 #encode_fields
458 Ok(())
459 }
460
461 fn is_default(&self) -> bool {
462 false }
464 }
465 })
466}
467
468#[proc_macro_derive(Decode, attributes(senax))]
496pub fn derive_decode(input: TokenStream) -> TokenStream {
497 let input = parse_macro_input!(input as DeriveInput);
498 let name = &input.ident;
499 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
500
501 let decode_fields = match &input.data {
502 Data::Struct(s) => match &s.fields {
503 Fields::Named(fields) => {
504 let mut field_idents = Vec::new();
505 let mut field_original_types = Vec::new();
506 let mut field_ids_for_match = Vec::new();
507 let mut field_is_option_flags = Vec::new();
508 let mut field_attrs_list = Vec::new();
509 let mut used_ids_struct_decode = HashMap::new();
510
511 for f in &fields.named {
512 let field_name_str = f.ident.as_ref().unwrap().to_string();
513 let field_attrs = get_field_attributes(&f.attrs, &field_name_str);
514
515 if let Some(dup_field_name) =
516 used_ids_struct_decode.insert(field_attrs.id, field_name_str.clone())
517 {
518 panic!("Field ID (0x{:016X}) is duplicated for struct '{}'. Please specify a different ID for field '{}' and '{}' using #[senax(id=...)].",
519 field_attrs.id, name, dup_field_name, field_name_str);
520 }
521
522 field_idents.push(f.ident.as_ref().unwrap().clone());
523 field_original_types.push(f.ty.clone());
524 field_ids_for_match.push(field_attrs.id);
525 field_is_option_flags.push(is_option_type(&f.ty));
526 field_attrs_list.push(field_attrs);
527 }
528
529 let field_value_definitions = field_idents
530 .iter()
531 .zip(field_original_types.iter())
532 .zip(field_attrs_list.iter())
533 .filter_map(|((ident, original_ty), attrs)| {
534 if attrs.skip_decode {
535 None
537 } else if is_option_type(original_ty) {
538 Some(quote! { #ident: #original_ty, })
539 } else {
540 Some(quote! { #ident: Option<#original_ty>, })
541 }
542 });
543
544 let match_arms = field_idents
545 .iter()
546 .zip(field_original_types.iter())
547 .zip(field_ids_for_match.iter())
548 .zip(field_attrs_list.iter())
549 .filter_map(|(((ident, original_ty), id_val), attrs)| {
550 if attrs.skip_decode {
551 None
553 } else if is_option_type(original_ty) {
554 let inner_ty = extract_inner_type_from_option(original_ty)
555 .unwrap_or_else(|| {
556 panic!(
557 "Failed to extract inner type from Option for field {}",
558 ident
559 )
560 });
561 Some(quote! {
562 x if x == #id_val => {
563 field_values.#ident = Some(<#inner_ty>::decode(reader)?);
564 }
565 })
566 } else {
567 Some(quote! {
568 x if x == #id_val => {
569 field_values.#ident = Some(<#original_ty>::decode(reader)?);
570 }
571 })
572 }
573 });
574
575 let struct_assignments = field_idents.iter()
576 .zip(field_is_option_flags.iter())
577 .zip(field_attrs_list.iter())
578 .map(|((ident, is_opt_flag), attrs)| {
579 if attrs.skip_decode {
580 quote! {
582 #ident: Default::default(),
583 }
584 } else if *is_opt_flag {
585 quote! {
586 #ident: field_values.#ident,
587 }
588 } else if attrs.default || attrs.skip_default {
589 quote! {
591 #ident: field_values.#ident.unwrap_or_default(),
592 }
593 } else {
594 quote! {
595 #ident: field_values.#ident.ok_or_else(||
596 senax_encoder::EncoderError::Decode(format!("Required field '{}' not found for struct {}", stringify!(#ident), stringify!(#name)))
597 )?,
598 }
599 }
600 });
601
602 quote! {
603 if reader.remaining() == 0 {
604 return Err(senax_encoder::EncoderError::InsufficientData);
605 }
606 let tag = reader.get_u8();
607 if tag != senax_encoder::TAG_STRUCT_NAMED {
608 return Err(senax_encoder::EncoderError::Decode(format!("Expected struct named tag ({}), got {}", senax_encoder::TAG_STRUCT_NAMED, tag)));
609 }
610
611 #[derive(Default)]
612 struct FieldValues {
613 #( #field_value_definitions )*
614 }
615
616 let mut field_values = FieldValues::default();
617
618 loop {
619 let field_id = senax_encoder::read_field_id_optimized(reader)?;
620 if field_id == 0 {
621 break;
622 }
623 match field_id {
624 #( #match_arms )*
625 _unknown_id => { senax_encoder::skip_value(reader)?; }
626 }
627 }
628
629 Ok(#name {
630 #( #struct_assignments )*
631 })
632 }
633 }
634 Fields::Unnamed(fields) => {
635 let field_count = fields.unnamed.len();
636 let field_deencode = fields.unnamed.iter().map(|f| {
637 let field_ty = &f.ty;
638 quote! {
639 <#field_ty>::decode(reader)?
640 }
641 });
642 quote! {
643 if reader.remaining() == 0 {
644 return Err(senax_encoder::EncoderError::InsufficientData);
645 }
646 let tag = reader.get_u8();
647 if tag != senax_encoder::TAG_STRUCT_UNNAMED {
648 return Err(senax_encoder::EncoderError::Decode(format!("Expected struct unnamed tag ({}), got {}", senax_encoder::TAG_STRUCT_UNNAMED, tag)));
649 }
650 let count = <usize>::decode(reader)?;
651 if count != #field_count {
652 return Err(senax_encoder::EncoderError::Decode(format!("Field count mismatch for struct {}: expected {}, got {}", stringify!(#name), #field_count, count)));
653 }
654 Ok(#name(
655 #(#field_deencode),*
656 ))
657 }
658 }
659 Fields::Unit => quote! {
660 if reader.remaining() == 0 {
661 return Err(senax_encoder::EncoderError::InsufficientData);
662 }
663 let tag = reader.get_u8();
664 if tag != senax_encoder::TAG_STRUCT_UNIT {
665 return Err(senax_encoder::EncoderError::Decode(format!("Expected struct unit tag ({}), got {}", senax_encoder::TAG_STRUCT_UNIT, tag)));
666 }
667 Ok(#name)
668 },
669 },
670 Data::Enum(e) => {
671 let mut unit_variant_arms = Vec::new();
672 let mut named_variant_arms = Vec::new();
673 let mut unnamed_variant_arms = Vec::new();
674 let mut used_ids_enum_decode = HashMap::new();
675
676 for v in &e.variants {
677 let variant_name_str = v.ident.to_string();
678 let variant_attrs = get_field_attributes(&v.attrs, &variant_name_str);
679 let variant_id = variant_attrs.id;
680
681 if let Some(dup_variant) =
682 used_ids_enum_decode.insert(variant_id, variant_name_str.clone())
683 {
684 panic!("Variant ID (0x{:016X}) is duplicated for enum '{}'. Please specify a different ID for variant '{}' and '{}' using #[senax(id=...)].",
685 variant_id, name, dup_variant, variant_name_str);
686 }
687
688 let variant_ident = &v.ident;
689 match &v.fields {
690 Fields::Named(fields) => {
691 let field_idents: Vec<_> = fields
692 .named
693 .iter()
694 .map(|f| f.ident.as_ref().unwrap().clone())
695 .collect();
696 let field_types: Vec<_> =
697 fields.named.iter().map(|f| f.ty.clone()).collect();
698 let field_attrs_list: Vec<_> = fields
699 .named
700 .iter()
701 .map(|f| {
702 get_field_attributes(
703 &f.attrs,
704 &f.ident.as_ref().unwrap().to_string(),
705 )
706 })
707 .collect();
708
709 let mut field_value_definitions_enum = Vec::new();
710 let mut match_arms_enum_named = Vec::new();
711 let mut struct_assignments_enum_named = Vec::new();
712
713 for (ident, ty, attrs) in izip!(
714 field_idents.iter(),
715 field_types.iter(),
716 field_attrs_list.iter()
717 ) {
718 if attrs.skip_decode {
719 } else if is_option_type(ty) {
721 field_value_definitions_enum.push(quote! { #ident: #ty, });
722 } else {
723 field_value_definitions_enum.push(quote! { #ident: Option<#ty>, });
724 }
725
726 if attrs.skip_decode {
727 } else if is_option_type(ty) {
729 let inner_ty = extract_inner_type_from_option(ty).unwrap();
730 let field_id = attrs.id;
731 match_arms_enum_named.push(quote! {
732 x if x == #field_id => { field_values.#ident = Some(<#inner_ty>::decode(reader)?); }
733 });
734 } else {
735 let field_id = attrs.id;
736 match_arms_enum_named.push(quote! {
737 x if x == #field_id => { field_values.#ident = Some(<#ty>::decode(reader)?); }
738 });
739 }
740
741 if attrs.skip_decode {
742 struct_assignments_enum_named
744 .push(quote! { #ident: Default::default(), });
745 } else if is_option_type(ty) {
746 struct_assignments_enum_named
747 .push(quote! { #ident: field_values.#ident, });
748 } else if attrs.default || attrs.skip_default {
749 struct_assignments_enum_named.push(quote! {
751 #ident: field_values.#ident.unwrap_or_default(),
752 });
753 } else {
754 struct_assignments_enum_named.push(quote! {
755 #ident: field_values.#ident.ok_or_else(|| senax_encoder::EncoderError::Decode(format!("Required field '{}' not found for variant {}::{}", stringify!(#ident), stringify!(#name), stringify!(#variant_ident))))?,
756 });
757 }
758 }
759
760 named_variant_arms.push(quote! {
761 x if x == #variant_id => {
762 #[derive(Default)]
763 struct FieldValues { #(#field_value_definitions_enum)* }
764 let mut field_values = FieldValues::default();
765 loop {
766 let field_id = {
767 if reader.remaining() == 0 { break; }
768 let id = senax_encoder::read_field_id_optimized(reader)?;
769 if id == 0 { break; }
770 id
771 };
772 match field_id {
773 #(#match_arms_enum_named)*
774 _unknown_id => { senax_encoder::skip_value(reader)?; }
775 }
776 }
777 Ok(#name::#variant_ident { #(#struct_assignments_enum_named)* })
778 }
779 });
780 }
781 Fields::Unnamed(fields) => {
782 let field_types: Vec<_> = fields.unnamed.iter().map(|f| &f.ty).collect();
783 let field_count = field_types.len();
784 unnamed_variant_arms.push(quote! {
785 x if x == #variant_id => {
786 let count = <usize>::decode(reader)?;
787 if count != #field_count {
788 return Err(senax_encoder::EncoderError::Decode(format!("Field count mismatch for variant {}::{}: expected {}, got {}", stringify!(#name), stringify!(#variant_ident), #field_count, count)));
789 }
790 Ok(#name::#variant_ident(
791 #(
792 <#field_types>::decode(reader)?,
793 )*
794 ))
795 }
796 });
797 }
798 Fields::Unit => {
799 unit_variant_arms.push(quote! {
800 x if x == #variant_id => {
801 Ok(#name::#variant_ident)
802 }
803 });
804 }
805 }
806 }
807 quote! {
808 if reader.remaining() == 0 {
809 return Err(senax_encoder::EncoderError::InsufficientData);
810 }
811 let tag = reader.get_u8();
812 match tag {
813 senax_encoder::TAG_ENUM => {
814 let variant_id = senax_encoder::read_field_id_optimized(reader)?;
815 match variant_id {
816 #(#unit_variant_arms)*
817 _ => Err(senax_encoder::EncoderError::Decode(format!("Unknown unit variant ID: 0x{:016X} for enum {}", variant_id, stringify!(#name))))
818 }
819 }
820 senax_encoder::TAG_ENUM_NAMED => {
821 let variant_id = senax_encoder::read_field_id_optimized(reader)?;
822 match variant_id {
823 #(#named_variant_arms)*
824 _ => Err(senax_encoder::EncoderError::Decode(format!("Unknown named variant ID: 0x{:016X} for enum {}", variant_id, stringify!(#name))))
825 }
826 }
827 senax_encoder::TAG_ENUM_UNNAMED => {
828 let variant_id = senax_encoder::read_field_id_optimized(reader)?;
829 match variant_id {
830 #(#unnamed_variant_arms)*
831 _ => Err(senax_encoder::EncoderError::Decode(format!("Unknown unnamed variant ID: 0x{:016X} for enum {}", variant_id, stringify!(#name))))
832 }
833 }
834 unknown_tag => Err(senax_encoder::EncoderError::Decode(format!("Unknown enum tag: {} for enum {}", unknown_tag, stringify!(#name))))
835 }
836 }
837 }
838 Data::Union(_) => unimplemented!("Unions are not supported"),
839 };
840
841 TokenStream::from(quote! {
842 impl #impl_generics senax_encoder::Decoder for #name #ty_generics #where_clause {
843 fn decode(reader: &mut bytes::Bytes) -> senax_encoder::Result<Self> {
844 use bytes::{Buf, BufMut};
845 #decode_fields
846 }
847 }
848 })
849}