reth_codecs_derive/compact/
enums.rs1use super::*;
2
3#[derive(Debug)]
4pub struct EnumHandler<'a> {
5 current_variant_index: u8,
6 fields_iterator: std::iter::Peekable<std::slice::Iter<'a, FieldTypes>>,
7 enum_lines: Vec<TokenStream2>,
8}
9
10impl<'a> EnumHandler<'a> {
11 pub fn new(fields: &'a FieldList) -> Self {
12 EnumHandler {
13 current_variant_index: 0u8,
14 enum_lines: vec![],
15 fields_iterator: fields.iter().peekable(),
16 }
17 }
18
19 pub fn next_field(&mut self) -> Option<&'a FieldTypes> {
20 self.fields_iterator.next()
21 }
22
23 pub fn generate_to(mut self, ident: &Ident) -> Vec<TokenStream2> {
24 while let Some(field) = self.next_field() {
25 match field {
26 FieldTypes::EnumVariant(name) => self.to(name, ident),
29 FieldTypes::EnumUnnamedField(_) | FieldTypes::StructField(_) => unreachable!(),
30 }
31 }
32 self.enum_lines
33 }
34
35 pub fn generate_from(mut self, ident: &Ident) -> Vec<TokenStream2> {
36 while let Some(field) = self.next_field() {
37 match field {
38 FieldTypes::EnumVariant(name) => self.from(name, ident),
41 FieldTypes::EnumUnnamedField(_) | FieldTypes::StructField(_) => unreachable!(),
42 }
43 }
44 self.enum_lines
45 }
46
47 pub fn from(&mut self, variant_name: &str, ident: &Ident) {
52 let variant_name = format_ident!("{variant_name}");
53 let current_variant_index = self.current_variant_index;
54
55 if let Some(next_field) = self.fields_iterator.peek() {
56 match next_field {
57 FieldTypes::EnumUnnamedField((next_ftype, use_alt_impl)) => {
58 let field_type = format_ident!("{next_ftype}");
60 let from_compact_ident = if *use_alt_impl {
61 format_ident!("specialized_from_compact")
62 } else {
63 format_ident!("from_compact")
64 };
65
66 self.enum_lines.push(quote! {
68 #current_variant_index => {
69 let (inner, new_buf) = #field_type::#from_compact_ident(buf, buf.len());
70 buf = new_buf;
71 #ident::#variant_name(inner)
72 }
73 });
74 self.fields_iterator.next();
75 }
76 FieldTypes::EnumVariant(_) => self.enum_lines.push(quote! {
77 #current_variant_index => #ident::#variant_name,
78 }),
79 FieldTypes::StructField(_) => unreachable!(),
80 };
81 } else {
82 self.enum_lines.push(quote! {
84 #current_variant_index => #ident::#variant_name,
85 });
86 }
87 self.current_variant_index += 1;
88 }
89
90 pub fn to(&mut self, variant_name: &str, ident: &Ident) {
95 let variant_name = format_ident!("{variant_name}");
96 let current_variant_index = self.current_variant_index;
97
98 if let Some(next_field) = self.fields_iterator.peek() {
99 match next_field {
100 FieldTypes::EnumUnnamedField((_, use_alt_impl)) => {
101 let to_compact_ident = if *use_alt_impl {
102 format_ident!("specialized_to_compact")
103 } else {
104 format_ident!("to_compact")
105 };
106
107 self.enum_lines.push(quote! {
109 #ident::#variant_name(field) => {
110 field.#to_compact_ident(&mut buffer);
111 #current_variant_index
112 },
113 });
114 self.fields_iterator.next();
115 }
116 FieldTypes::EnumVariant(_) => self.enum_lines.push(quote! {
117 #ident::#variant_name => #current_variant_index,
118 }),
119 FieldTypes::StructField(_) => unreachable!(),
120 };
121 } else {
122 self.enum_lines.push(quote! {
124 #ident::#variant_name => #current_variant_index,
125 });
126 }
127 self.current_variant_index += 1;
128 }
129}