| 59 | } |
| 60 | |
| 61 | pub trait Derive<const ITEM_COUNT: usize> { |
| 62 | type Item: Item; |
| 63 | const ALL: [Self::Item; ITEM_COUNT]; |
| 64 | |
| 65 | /// `Encode` in `T: Encode`. |
| 66 | fn bound(&self) -> Path; |
| 67 | |
| 68 | /// Generates the derive implementation. |
| 69 | fn derive_impl( |
| 70 | &self, |
| 71 | output: [TokenStream; ITEM_COUNT], |
| 72 | ident: Ident, |
| 73 | generics: Generics, |
| 74 | ) -> TokenStream; |
| 75 | |
| 76 | fn field_attrs( |
| 77 | &self, |
| 78 | fields: &Fields, |
| 79 | attrs: &BitcodeAttrs, |
| 80 | bounds: &mut FieldBounds, |
| 81 | ) -> Result<Vec<BitcodeAttrs>> { |
| 82 | fields |
| 83 | .iter() |
| 84 | .map(|field| { |
| 85 | let field_attrs = BitcodeAttrs::parse_field(&field.attrs, attrs)?; |
| 86 | bounds.add_bound_type(field.clone(), &field_attrs, self.bound()); |
| 87 | Ok(field_attrs) |
| 88 | }) |
| 89 | .collect() |
| 90 | } |
| 91 | |
| 92 | fn derive(&self, mut input: DeriveInput) -> Result<TokenStream> { |
| 93 | let attrs = BitcodeAttrs::parse_derive(&input.attrs)?; |
| 94 | let ident = input.ident; |
| 95 | syn::visit_mut::visit_data_mut(&mut ReplaceSelves(&ident), &mut input.data); |
| 96 | let mut bounds = FieldBounds::default(); |
| 97 | |
| 98 | let output = match input.data { |
| 99 | Data::Struct(DataStruct { ref fields, .. }) => { |
| 100 | // Only used for adding `bounds`. Would be used by `#[bitcode(with_serde)]`. |
| 101 | let field_attrs = self.field_attrs(fields, &attrs, &mut bounds)?; |
| 102 | let _ = field_attrs; |
| 103 | |
| 104 | let destructure_fields = &destructure_fields(fields); |
| 105 | Self::ALL.map(|item| { |
| 106 | let field_impls = item.field_impls(None, fields); |
| 107 | item.struct_impl(&ident, destructure_fields, &field_impls) |
| 108 | }) |
| 109 | } |
| 110 | Data::Enum(data_enum) => { |
| 111 | let max_variants = VariantIndex::MAX as usize + 1; |
| 112 | if data_enum.variants.len() > max_variants { |
| 113 | return err( |
| 114 | &ident, |
| 115 | &format!("enums with more than {max_variants} variants are not supported"), |
| 116 | ); |
| 117 | } |
| 118 | |