1extern crate proc_macro;
2
3use quote::{format_ident, quote};
4use syn::{
5 parse_macro_input, punctuated::Punctuated, token::Comma, Attribute, Data, DeriveInput, Fields,
6 Lit, PathArguments, Type,
7};
8
9#[proc_macro_derive(
10 ToBytes,
11 attributes(
12 bits,
13 dyn_int,
14 dyn_length,
15 key_dyn_length,
16 val_dyn_length,
17 toggles,
18 toggled_by,
19 length_for,
20 length_by,
21 variant_for,
22 variant_by,
23 no_discriminator
24 )
25)]
26pub fn generate_code_to_bytes(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
27 generate_code_binary_serializer(false, input)
28}
29
30#[proc_macro_derive(
31 FromBytes,
32 attributes(
33 bits,
34 dyn_int,
35 key_dyn_length,
36 val_dyn_length,
37 dyn_length,
38 toggles,
39 toggled_by,
40 length_for,
41 length_by,
42 variant_for,
43 variant_by,
44 no_discriminator
45 )
46)]
47pub fn generate_code_from_bytes(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
48 generate_code_binary_serializer(true, input)
49}
50
51fn generate_code_binary_serializer(
52 read: bool,
53 input: proc_macro::TokenStream,
54) -> proc_macro::TokenStream {
55 let ast = parse_macro_input!(input as DeriveInput);
57
58 match ast.data {
59 Data::Struct(ref data) => generate_struct_serializer(read, &ast, data),
60 Data::Enum(ref data) => generate_enum_serializer(read, &ast, data),
61 _ => panic!("ToBytes can only be used on structs"),
62 }
63}
64
65fn generate_struct_serializer(
66 read: bool,
67 ast: &DeriveInput,
68 data_struct: &syn::DataStruct,
69) -> proc_macro::TokenStream {
70 let fields = &data_struct.fields;
71 let struct_name = &ast.ident;
72
73 let field_serializations = fields.iter().map(|field| {
75 let field_name = field
76 .ident
77 .as_ref()
78 .expect("ToBytes does not support fields without a name");
79
80 let field_type = &field.ty;
81
82 let mut toggle_key = None;
83 let mut variant_key = None;
84 let mut length_key = None;
85 let mut toggled_by = None;
86 let mut variant_by = None;
87 let mut length_by = None;
88 let mut is_dynamic_int = false;
89 let mut has_dynamic_length = false;
90 let mut bits_count = None;
91 let mut key_dyn_length = false;
92 let mut val_dyn_length = false;
93
94 for attr in field.attrs.iter() {
96 let ident = attr.path().get_ident().map(|i| i.clone().to_string());
97 match ident.as_deref() {
98 Some("dyn_int") => is_dynamic_int = true,
99 Some("dyn_length") => has_dynamic_length = true,
100 Some("key_dyn_length") => key_dyn_length = true,
101 Some("val_dyn_length") => val_dyn_length = true,
102 Some("toggles") => toggle_key = get_string_value_from_attribute(attr),
103 Some("variant_for") => variant_key = get_string_value_from_attribute(attr),
104 Some("length_for") => length_key = get_string_value_from_attribute(attr),
105 Some("toggled_by") => toggled_by = get_string_value_from_attribute(attr),
106 Some("variant_by") => variant_by = get_string_value_from_attribute(attr),
107 Some("length_by") => length_by = get_string_value_from_attribute(attr),
108 Some("bits") => bits_count = get_int_value_from_attribute(attr).map(|b| b as u8),
109 _ => {}
110 }
112 }
113
114 let toggles = if let Some(key) = toggle_key {
116 if read {
117 quote! {
118 _p_config.set_toggle(#key, _p_val);
119 }
120 } else {
121 quote! {
122 _p_config.set_toggle(#key, *_p_val);
123 }
124 }
125 } else { quote! {} };
126
127 let length = if let Some(key) = length_key {
129 if read {
130 quote! {
131 _p_config.set_length(#key, _p_val as usize);
132 }
133 } else {
134 quote! {
135 _p_config.set_length(#key, *_p_val as usize);
136 }
137 }
138 } else { quote! {} };
139
140 let variant = if let Some(key) = variant_key {
142 if read {
143 quote! {
144 _p_config.set_variant(#key, _p_val as u8);
145 }
146 } else {
147 quote! {
148 _p_config.set_variant(#key, *_p_val as u8);
149 }
150 }
151 } else { quote! {} };
152
153 let before = if read {
155 quote! {}
156 } else {
157 quote! {
158 let _p_val = &self.#field_name;
159 #toggles
160 #length
161 #variant
162 }
163 };
164
165 let after = if read {
166 quote! {
167 let #field_name = _p_val;
168 #toggles
169 #length
170 #variant
171 }
172 } else {
173 quote! {}
174 };
175
176 let handle_field = generate_code_for_handling_field(
177 read,
178 field_type,
179 field_name,
180 bits_count,
181 toggled_by,
182 variant_by,
183 length_by,
184 is_dynamic_int,
185 has_dynamic_length,
186 key_dyn_length,
187 val_dyn_length,
188 0,
189 );
190
191 quote! {
192 #before
193 #handle_field
194 #after
195 }
196 });
197
198 let error_type = generate_error_type(read);
199 let serializer_code = if read {
200 let vars = fields.iter().map(|f| f.ident.as_ref().unwrap());
201
202 quote! {
204 impl binary_codec::BinaryDeserializer for #struct_name {
205 fn from_bytes(bytes: &[u8], config: Option<&mut binary_codec::SerializerConfig>) -> Result<Self, #error_type> {
206 let mut _new_config = binary_codec::SerializerConfig::new();
207 let _p_config = config.unwrap_or(&mut _new_config);
208 let _p_bytes = bytes;
209
210 #(#field_serializations)*
211
212 Ok(Self {
213 #(#vars),*
214 })
215 }
216 }
217 }
218 } else {
219 quote! {
221 impl binary_codec::BinarySerializer for #struct_name {
222 fn to_bytes(&self, config: Option<&mut binary_codec::SerializerConfig>) -> Result<Vec<u8>, #error_type> {
223 let mut bytes = Vec::new();
224 Self::write_bytes(self, &mut bytes, config)?;
225 Ok(bytes)
226 }
227
228 fn write_bytes(&self, buffer: &mut Vec<u8>, config: Option<&mut binary_codec::SerializerConfig>) -> Result<(), #error_type> {
229 let mut _new_config = binary_codec::SerializerConfig::new();
230 let _p_config = config.unwrap_or(&mut _new_config);
231 let _p_bytes = buffer;
232
233 #(#field_serializations)*
234 Ok(())
235 }
236 }
237 }
238 };
239
240 serializer_code.into()
241}
242
243fn generate_enum_serializer(
244 read: bool,
245 ast: &DeriveInput,
246 data_enum: &syn::DataEnum,
247) -> proc_macro::TokenStream {
248 let enum_name = &ast.ident;
249 let error_type = generate_error_type(read);
250
251 let mut no_disc_prefix = false;
252
253 for attr in ast.attrs.iter() {
255 if attr.path().is_ident("no_discriminator") {
257 no_disc_prefix = true;
258 }
259 }
260
261 let variants = data_enum.variants.iter().enumerate().map(|(i, variant)| {
263 let var_ident = &variant.ident;
264 let disc_value = i as u8; let fields = &variant.fields;
266
267 let write_disc = if no_disc_prefix {
268 quote! {}
269 } else {
270 quote! {
271 let _p_disc: u8 = #disc_value;
272 binary_codec::fixed_int::FixedInt::write(_p_disc, _p_bytes, _p_config)?;
273 }
274 };
275
276 match fields {
277 Fields::Unit => {
278 if read {
279 quote! {
280 #disc_value => {
281 Ok(Self::#var_ident)
282 }
283 }
284 } else {
285 quote! {
286 Self::#var_ident => {
287 #write_disc
288 }
289 }
290 }
291 }
292 Fields::Unnamed(fields_unnamed) => {
293 let field_count = fields_unnamed.unnamed.len();
294 let idents: Vec<_> = (0..field_count).map(|i| format_ident!("f{}", i)).collect();
295 let ident_refs: Vec<&syn::Ident> = idents.iter().collect();
296 let field_serializations =
297 generate_enum_field_serializations(read, &ident_refs, &fields_unnamed.unnamed);
298 if read {
299 quote! {
300 #disc_value => {
301 #(#field_serializations)*
302 Ok(Self::#var_ident(#(#idents),*))
303 }
304 }
305 } else {
306 quote! {
307 Self::#var_ident(#(#idents),*) => {
308 #write_disc
309 #(#field_serializations)*
310 }
311 }
312 }
313 }
314 Fields::Named(fields_named) => {
315 let field_idents: Vec<_> = fields_named
316 .named
317 .iter()
318 .map(|f| f.ident.as_ref().unwrap())
319 .collect();
320
321 let field_serializations =
322 generate_enum_field_serializations(read, &field_idents, &fields_named.named);
323
324 if read {
325 quote! {
326 #disc_value => {
327 #(#field_serializations)*
328 Ok(Self::#var_ident { #(#field_idents),* })
329 }
330 }
331 } else {
332 quote! {
333 Self::#var_ident { #(#field_idents),* } => {
334 #write_disc
335 #(#field_serializations)*
336 }
337 }
338 }
339 }
340 }
341 });
342
343 if read {
344 quote! {
345 impl binary_codec::BinaryDeserializer for #enum_name {
346 fn from_bytes(bytes: &[u8], config: Option<&mut binary_codec::SerializerConfig>) -> Result<Self, #error_type> {
347 let mut _new_config = binary_codec::SerializerConfig::new();
348 let _p_config = config.unwrap_or(&mut _new_config);
349 let _p_bytes = bytes;
350
351 let _p_disc = if let Some(disc) = _p_config.discriminator.take() {
352 disc
353 } else {
354 binary_codec::fixed_int::FixedInt::read(_p_bytes, _p_config)?
355 };
356
357 match _p_disc {
358 #(#variants,)*
359 _ => Err(#error_type::UnknownDiscriminant(_p_disc)),
360 }
361 }
362 }
363 }
364 .into()
365 } else {
366 quote! {
367 impl binary_codec::BinarySerializer for #enum_name {
368 fn to_bytes(&self, config: Option<&mut binary_codec::SerializerConfig>) -> Result<Vec<u8>, #error_type> {
369 let mut bytes = Vec::new();
370 Self::write_bytes(self, &mut bytes, config)?;
371 Ok(bytes)
372 }
373
374 fn write_bytes(&self, buffer: &mut Vec<u8>, config: Option<&mut binary_codec::SerializerConfig>) -> Result<(), #error_type> {
375 let mut _new_config = binary_codec::SerializerConfig::new();
376 let _p_config = config.unwrap_or(&mut _new_config);
377 let _p_bytes = buffer;
378
379 match self {
380 #(#variants)*
381 }
382
383 Ok(())
384 }
385 }
386 }
387 .into()
388 }
389}
390
391fn generate_enum_field_serializations(
392 read: bool,
393 idents: &Vec<&syn::Ident>,
394 fields: &Punctuated<syn::Field, Comma>,
395) -> Vec<proc_macro2::TokenStream> {
396 let field_serializations = fields.iter().enumerate().map(|(i, f)| {
397 let field_type = &f.ty;
398 let field_ident = &idents[i];
399
400 let handle_field = generate_code_for_handling_field(
401 read,
402 field_type,
403 field_ident,
404 None,
405 None,
406 None,
407 None,
408 false,
409 false,
410 false,
411 false,
412 0,
413 );
414
415 if read {
416 quote! {
417 #handle_field
418 let #field_ident = _p_val;
419 }
420 } else {
421 quote! {
422 let _p_val = #field_ident;
423 #handle_field
424 }
425 }
426 });
427 field_serializations.collect()
428}
429
430fn generate_code_for_handling_field(
431 read: bool,
432 field_type: &Type,
433 field_name: &syn::Ident,
434 bits_count: Option<u8>,
435 toggled_by: Option<String>,
436 variant_by: Option<String>,
437 length_by: Option<String>,
438 is_dynamic_int: bool,
439 has_dynamic_length: bool,
440 key_dyn_length: bool,
441 val_dyn_length: bool,
442 level: usize,
443) -> proc_macro2::TokenStream {
444 if let Type::Path(path) = field_type {
445 let path = &path.path;
446
447 if let Some(ident) = path.get_ident() {
448 let ident_name = ident.to_string();
449
450 match ident_name.as_str() {
452 "bool" => {
453 if read {
454 quote! { let _p_val = binary_codec::dynamics::read_bool(_p_bytes, _p_config)?; }
455 } else {
456 quote! { binary_codec::dynamics::write_bool(*_p_val, _p_bytes, _p_config)?; }
457 }
458 }
459 "i8" => {
460 if let Some(bits_count) = bits_count.as_ref() {
461 if *bits_count < 1 || *bits_count > 7 {
462 panic!("Bits count should be between 1 and 7");
463 }
464
465 if read {
466 quote! { let _p_val = binary_codec::dynamics::read_small_dynamic_signed(_p_bytes, _p_config, #bits_count)?; }
467 } else {
468 quote! { binary_codec::dynamics::write_small_dynamic_signed(*_p_val, _p_bytes, _p_config, #bits_count)?; }
469 }
470 } else {
471 if read {
472 quote! {
473 let _p_val = binary_codec::dynamics::read_zigzag(_p_bytes, _p_config)?;
474 }
475 } else {
476 quote! {
477 binary_codec::dynamics::write_zigzag(*_p_val, _p_bytes, _p_config)?;
478 }
479 }
480 }
481 }
482 "u8" => {
483 if let Some(bits_count) = bits_count.as_ref() {
484 if *bits_count < 1 || *bits_count > 7 {
485 panic!("Bits count should be between 1 and 7");
486 }
487
488 if read {
489 quote! { let _p_val = binary_codec::dynamics::read_small_dynamic_unsigned(_p_bytes, _p_config, #bits_count)?; }
490 } else {
491 quote! { binary_codec::dynamics::write_small_dynamic_unsigned(*_p_val, _p_bytes, _p_config, #bits_count)?; }
492 }
493 } else {
494 if read {
495 quote! {
496 let _p_val = binary_codec::fixed_int::FixedInt::read(_p_bytes, _p_config)?;
497 }
498 } else {
499 quote! {
500 binary_codec::fixed_int::FixedInt::write(*_p_val, _p_bytes, _p_config)?;
501 }
502 }
503 }
504 }
505 "u16" | "u32" | "u64" | "u128" => {
506 if is_dynamic_int {
507 let dynint: proc_macro2::TokenStream = generate_dynint(read);
508 if read {
509 quote! {
510 #dynint
511 let _p_val = _p_dyn as #ident;
512 }
513 } else {
514 quote! {
515 let _p_dyn = *_p_val as u128;
516 #dynint
517 }
518 }
519 } else {
520 if read {
521 quote! {
522 let _p_val = binary_codec::fixed_int::FixedInt::read(_p_bytes, _p_config)?;
523 }
524 } else {
525 quote! {
526 binary_codec::fixed_int::FixedInt::write(*_p_val, _p_bytes, _p_config)?;
527 }
528 }
529 }
530 }
531 "i16" | "i32" | "i64" | "i128" => {
532 if is_dynamic_int {
533 let dynint: proc_macro2::TokenStream = generate_dynint(read);
534 if read {
535 quote! {
536 #dynint
537 let _p_val: #ident = binary_codec::fixed_int::ZigZag::to_signed(_p_dyn);
538 }
539 } else {
540 quote! {
541 let _p_dyn = binary_codec::fixed_int::ZigZag::to_unsigned(*_p_val) as u128;
542 #dynint
543 }
544 }
545 } else {
546 if read {
547 quote! {
548 let _p_val = binary_codec::fixed_int::read_zigzag(_p_bytes, _p_config)?;
549 }
550 } else {
551 quote! {
552 binary_codec::fixed_int::write_zigzag(*_p_val, _p_bytes, _p_config)?;
553 }
554 }
555 }
556 }
557 "String" => {
558 let size_key = generate_size_key(length_by, has_dynamic_length).1;
559
560 if read {
561 quote! {
562 let _p_val = binary_codec::variable::read_string(_p_bytes, #size_key, _p_config)?;
563 }
564 } else {
565 quote! {
566 binary_codec::variable::write_string(_p_val, #size_key, _p_bytes, _p_config)?;
567 }
568 }
569 }
570 _ => {
571 let size_key = generate_size_key(length_by, has_dynamic_length).1;
572
573 let variant_code = if variant_by.is_some() {
574 quote! {
575 _p_config.discriminator = _p_config.get_variant(#variant_by);
576 }
577 } else { quote! {} };
578
579 if read {
580 quote! {
581 #variant_code
582 let _p_val = binary_codec::variable::read_object(_p_bytes, #size_key, _p_config)?;
583 }
584 } else {
585 quote! {
586 #variant_code
587 binary_codec::variable::write_object(_p_val, #size_key, _p_bytes, _p_config)?;
588 }
589 }
590 }
591 }
592 } else {
593 if path.segments.len() == 1 {
595 let ident = &path.segments[0].ident;
596 let ident_name = ident.to_string();
597
598 match ident_name.as_ref() {
599 "Option" => {
600 let inner_type = get_inner_type(path).expect("Option missing inner type");
601 let handle = generate_code_for_handling_field(
602 read,
603 inner_type,
604 field_name,
605 bits_count,
606 None,
607 variant_by,
608 length_by,
609 is_dynamic_int,
610 has_dynamic_length,
611 key_dyn_length,
612 val_dyn_length,
613 level + 1,
614 );
615 let option_name: syn::Ident = format_ident!("__option_{}", level);
616
617 if let Some(toggled_by) = toggled_by {
618 let toggled_by = quote! {
620 _p_config.get_toggle(#toggled_by).unwrap_or(false)
621 };
622
623 if read {
624 quote! {
625 let mut #option_name: Option<#inner_type> = None;
626 if #toggled_by {
627 #handle
628 #option_name = Some(_p_val);
629 }
630 let _p_val = #option_name;
631 }
632 } else {
633 quote! {
634 if #toggled_by {
635 let _p_val = _p_val.as_ref().expect("Expected Some value, because toggled_by field is true");
636 #handle
637 }
638 }
639 }
640 } else {
641 if read {
643 quote! {
644 let mut #option_name: Option<#inner_type> = None;
645 if _p_config.next_reset_bits_pos() < _p_bytes.len() {
646 #handle
647 #option_name = Some(_p_val);
648 }
649 let _p_val = #option_name;
650 }
651 } else {
652 quote! {
653 if let Some(_p_val) = _p_val.as_ref() {
654 #handle
655 }
656 }
657 }
658 }
659 }
660 "Vec" => {
661 let vec_name = format_ident!("__val_{}", level);
662 let inner_type = get_inner_type(path).expect("Vec missing inner type");
663 let handle = generate_code_for_handling_field(
664 read,
665 inner_type,
666 field_name,
667 bits_count,
668 None,
669 None,
670 None,
671 is_dynamic_int,
672 val_dyn_length,
673 false,
674 false,
675 level + 1,
676 );
677
678 let (has_size, size_key) = generate_size_key(length_by, has_dynamic_length);
679
680 let write_code = quote! {
681 for _p_val in _p_val {
682 #handle
683 }
684 };
685
686 if has_size {
687 if read {
688 quote! {
689 let _p_len = binary_codec::utils::get_read_size(_p_bytes, #size_key, _p_config)?;
690 let mut #vec_name = Vec::<#inner_type>::with_capacity(_p_len);
691 for _ in 0.._p_len {
692 #handle
693 #vec_name.push(_p_val);
694 }
695 let _p_val = #vec_name;
696 }
697 } else {
698 quote! {
699 let _p_len = _p_val.len();
700 binary_codec::utils::write_size(_p_len, #size_key, _p_bytes, _p_config)?;
701 #write_code
702 }
703 }
704 } else {
705 if read {
706 quote! {
707 let mut #vec_name = Vec::<#inner_type>::new();
708 while _p_config.next_reset_bits_pos() < _p_bytes.len() {
709 #handle
710 #vec_name.push(_p_val);
711 }
712 let _p_val = #vec_name;
713 }
714 } else {
715 quote! {
716 #write_code
717 }
718 }
719 }
720 }
721 "HashMap" => {
722 let (key_type, value_type) =
723 get_two_types(path).expect("Failed to get HashMap types");
724
725 let handle_key = generate_code_for_handling_field(
726 read,
727 key_type,
728 field_name,
729 None,
730 None,
731 None,
732 None,
733 is_dynamic_int,
734 key_dyn_length,
735 false,
736 false,
737 level + 1,
738 );
739
740 let handle_value = generate_code_for_handling_field(
741 read,
742 value_type,
743 field_name,
744 None,
745 None,
746 None,
747 None,
748 is_dynamic_int,
749 val_dyn_length,
750 false,
751 false,
752 level + 1,
753 );
754
755 let (has_size, size_key) = generate_size_key(length_by, has_dynamic_length);
756
757 let write_code = quote! {
758 for (key, value) in _p_val {
759 let _p_val = key;
760 #handle_key
761 let _p_val = value;
762 #handle_value
763 }
764 };
765
766 if read {
767 if has_size {
768 quote! {
769 let _p_len = binary_codec::utils::get_read_size(_p_bytes, #size_key, _p_config)?;
770 let mut _p_map = std::collections::HashMap::<#key_type, #value_type>::with_capacity(_p_len);
771 for _ in 0.._p_len {
772 let _p_key;
773 #handle_key
774 _p_key = _p_val;
775 let _p_value;
776 #handle_value
777 _p_value = _p_val;
778 _p_map.insert(_p_key, _p_value);
779 }
780 let _p_val = _p_map;
781 }
782 } else {
783 quote! {
784 let mut _p_map = std::collections::HashMap::<#key_type, #value_type>::new();
785 while _p_config.next_reset_bits_pos() < _p_bytes.len() {
786 let _p_key;
787 #handle_key
788 _p_key = _p_val;
789 let _p_value;
790 #handle_value
791 _p_value = _p_val;
792 _p_map.insert(_p_key, _p_value);
793 }
794 let _p_val = _p_map;
795 }
796 }
797 } else {
798 if has_size {
799 quote! {
800 let _p_len = _p_val.len();
801 binary_codec::utils::write_size(_p_len, #size_key, _p_bytes, _p_config)?;
802 #write_code
803 }
804 } else {
805 quote! {
806 #write_code
807 }
808 }
809 }
810 }
811 _ => {
812 panic!("Type not implemented")
813 }
814 }
815 } else {
816 panic!("Multi-segment paths are not supported");
817 }
818 }
819 } else if let Type::Array(array) = field_type {
820 let len: usize = if let syn::Expr::Lit(ref arr_len_lit) = array.len {
821 if let Lit::Int(ref lit_int) = arr_len_lit.lit {
822 lit_int
823 .base10_parse()
824 .expect("Failed to parse literal to usize")
825 } else {
826 panic!("Expected an int to determine array length");
827 }
828 } else {
829 panic!("Expected literal to determine array length");
830 };
831
832 let array_type = &array.elem;
833 let handle = generate_code_for_handling_field(
834 read,
835 array_type,
836 field_name,
837 bits_count,
838 None,
839 None,
840 None,
841 is_dynamic_int,
842 val_dyn_length,
843 false,
844 false,
845 level + 1,
846 );
847
848 let array_name = format_ident!("__val_{}", level);
849
850 if read {
851 quote! {
852 let mut #array_name = Vec::<#array_type>::with_capacity(#len);
853 for _ in 0..#len {
854 #handle;
855 #array_name.push(_p_val);
856 }
857 let _p_val = TryInto::<[#array_type; #len]>::try_into(#array_name).expect("Failed to convert Vec to array");
858 }
859 } else {
860 quote! {
861 for _p_val in _p_val {
862 #handle
863 }
864 }
865 }
866 } else {
867 panic!("Field type of '{:?}' not supported", field_name);
868 }
869}
870
871fn generate_error_type(read: bool) -> proc_macro2::TokenStream {
872 if read {
873 quote! { binary_codec::DeserializationError }
874 } else {
875 quote! { binary_codec::SerializationError }
876 }
877}
878
879fn generate_size_key(length_by: Option<String>, has_dynamic_length: bool) -> (bool, proc_macro2::TokenStream) {
880 if let Some(length_by) = length_by.as_ref() {
881 (true, quote! { Some(#length_by) })
882 } else if has_dynamic_length {
883 (true, quote! { Some("__dynamic") })
884 } else {
885 (false, quote! { None })
886 }
887}
888
889fn get_string_value_from_attribute(
890 attr: &Attribute
891) -> Option<String> {
892 match &attr.meta {
893 syn::Meta::Path(_) => {
894 None
895 }
896 syn::Meta::List(list_value) => {
897 for token in list_value.tokens.clone().into_iter() {
899 if let proc_macro2::TokenTree::Literal(lit) = token {
900 return Some(lit.to_string().trim_matches('"').to_string());
901 }
902 }
903
904 None
905 }
906 syn::Meta::NameValue(name_value) => {
907 if let syn::Expr::Lit(lit_expr) = &name_value.value {
908 if let Lit::Str(lit_str) = &lit_expr.lit {
909 return Some(lit_str.value());
910 }
911 }
912
913 None
914 }
915 }
916}
917
918fn get_int_value_from_attribute(attr: &Attribute) -> Option<i32> {
919 match &attr.meta {
920 syn::Meta::Path(_) => {
921 None
922 }
923 syn::Meta::List(list_value) => {
924 for token in list_value.tokens.clone().into_iter() {
926 if let proc_macro2::TokenTree::Literal(lit) = token {
927 if let Ok(val) = lit.to_string().parse::<i32>() {
928 return Some(val);
929 }
930 }
931 }
932
933 None
934 }
935 syn::Meta::NameValue(name_value) => {
936 if let syn::Expr::Lit(lit_expr) = &name_value.value {
937 if let Lit::Int(lit_int) = &lit_expr.lit {
938 return Some(lit_int.base10_parse().expect("Not a valid int value"));
939 }
940 }
941
942 None
943 }
944 }
945}
946
947fn get_inner_type(path: &syn::Path) -> Option<&syn::Type> {
948 if let Some(PathArguments::AngleBracketed(args)) =
949 path.segments.last().map(|seg| &seg.arguments)
950 {
951 if let Some(arg) = args.args.first() {
952 if let syn::GenericArgument::Type(inner_type) = arg {
953 return Some(inner_type);
954 }
955 }
956 }
957
958 None
959}
960
961fn get_two_types(path: &syn::Path) -> Option<(&syn::Type, &syn::Type)> {
962 if let Some(PathArguments::AngleBracketed(args)) =
963 path.segments.last().map(|seg| &seg.arguments)
964 {
965 let mut types = args.args.iter().filter_map(|arg| {
966 if let syn::GenericArgument::Type(inner_type) = arg {
967 Some(inner_type)
968 } else {
969 None
970 }
971 });
972
973 if let (Some(t1), Some(t2)) = (types.next(), types.next()) {
974 return Some((t1, t2));
975 }
976 }
977
978 None
979}
980
981fn generate_dynint(read: bool) -> proc_macro2::TokenStream {
982 if read {
983 quote! {
984 let _p_dyn = binary_codec::dyn_int::read_dynint(_p_bytes, _p_config)?;
985 }
986 } else {
987 quote! {
988 binary_codec::dyn_int::write_dynint(_p_dyn, _p_bytes, _p_config)?;
989 }
990 }
991}