Skip to content

Commit

Permalink
feat!: add DiscriminantValue to Definition::Enum::variants tuples
Browse files Browse the repository at this point in the history
  • Loading branch information
dj8yf0μl committed Sep 25, 2023
1 parent 2e02f68 commit ab9add0
Show file tree
Hide file tree
Showing 25 changed files with 134 additions and 81 deletions.
3 changes: 2 additions & 1 deletion borsh-derive/src/internals/deserialize/enums/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ pub fn process(input: &ItemEnum, cratename: Path) -> syn::Result<TokenStream2> {
let variant_body = process_variant(variant, &cratename, &mut generics_output)?;
let variant_ident = &variant.ident;

let discriminant_value = discriminants.get(variant_ident, use_discriminant, variant_idx)?;
let discriminant_value =
discriminants.get(variant_ident, use_discriminant, variant_idx, false)?;
variant_arms.extend(quote! {
if variant_tag == #discriminant_value { #name::#variant_ident #variant_body } else
});
Expand Down
3 changes: 3 additions & 0 deletions borsh-derive/src/internals/enum_discriminant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ impl Discriminants {
variant_ident: &Ident,
use_discriminant: bool,
variant_idx: usize,
cast_to_i64: bool,
) -> syn::Result<TokenStream> {
let variant_idx = u8::try_from(variant_idx).map_err(|err| {
syn::Error::new(
Expand All @@ -41,6 +42,8 @@ impl Discriminants {
let result = if use_discriminant {
let discriminant_value = self.0.get(variant_ident).unwrap();
quote! { #discriminant_value }
} else if cast_to_i64 {
quote! { #variant_idx as i64 }
} else {
quote! { #variant_idx }
};
Expand Down
17 changes: 14 additions & 3 deletions borsh-derive/src/internals/schema/enums/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ use quote::{quote, ToTokens};
use std::collections::HashSet;
use syn::{Fields, Generics, Ident, ItemEnum, ItemStruct, Path, Variant, Visibility};

use crate::internals::{attributes::field, generics, schema};
use crate::internals::{
attributes::{field, item},
enum_discriminant::Discriminants,
generics, schema,
};

fn transform_variant_fields(mut input: Fields) -> Fields {
match input {
Expand Down Expand Up @@ -31,14 +35,20 @@ pub fn process(input: &ItemEnum, cratename: Path) -> syn::Result<TokenStream2> {
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
let mut where_clause = generics::default_where(where_clause);
let mut generics_output = schema::GenericsOutput::new(&generics);
let use_discriminant = item::contains_use_discriminant(input)?;
let discriminants = Discriminants::new(&input.variants);

// Generate functions that return the schema for variants.
let mut variants_defs = vec![];
let mut inner_defs = TokenStream2::new();
let mut add_recursive_defs = TokenStream2::new();
for variant in &input.variants {
for (variant_idx, variant) in input.variants.iter().enumerate() {
let variant_ident = &variant.ident;
let discriminant_value =
discriminants.get(variant_ident, use_discriminant, variant_idx, true)?;
let variant_output = process_variant(
variant,
discriminant_value,
&cratename,
&enum_name,
&generics,
Expand Down Expand Up @@ -84,6 +94,7 @@ struct VariantOutput {

fn process_variant(
variant: &Variant,
discriminant_value: TokenStream2,
cratename: &Path,
enum_name: &str,
enum_generics: &Generics,
Expand All @@ -102,7 +113,7 @@ fn process_variant(
<#full_variant_ident #inner_struct_ty_generics as #cratename::BorshSchema>::add_definitions_recursively(definitions);
};
let variant_entry = quote! {
(#variant_name.to_string(), <#full_variant_ident #inner_struct_ty_generics>::declaration())
(#discriminant_value, #variant_name.to_string(), <#full_variant_ident #inner_struct_ty_generics>::declaration())
};
Ok(VariantOutput {
inner_struct,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,10 @@ impl borsh::BorshSchema for A {
let definition = borsh::schema::Definition::Enum {
tag_width: 1,
variants: borsh::__private::maybestd::vec![
("Bacon".to_string(), < ABacon > ::declaration()), ("Eggs".to_string(), <
AEggs > ::declaration()), ("Salad".to_string(), < ASalad >
::declaration()), ("Sausage".to_string(), < ASausage > ::declaration())
(0u8 as i64, "Bacon".to_string(), < ABacon > ::declaration()), (1u8 as
i64, "Eggs".to_string(), < AEggs > ::declaration()), (2u8 as i64, "Salad"
.to_string(), < ASalad > ::declaration()), (3u8 as i64, "Sausage"
.to_string(), < ASausage > ::declaration())
],
};
borsh::schema::add_definition(Self::declaration(), definition, definitions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ where
let definition = borsh::schema::Definition::Enum {
tag_width: 1,
variants: borsh::__private::maybestd::vec![
("Bacon".to_string(), < ABacon > ::declaration()), ("Eggs".to_string(), <
AEggs > ::declaration()), ("Salad".to_string(), < ASalad < C > >
::declaration()), ("Sausage".to_string(), < ASausage < W > >
::declaration())
(0u8 as i64, "Bacon".to_string(), < ABacon > ::declaration()), (1u8 as
i64, "Eggs".to_string(), < AEggs > ::declaration()), (2u8 as i64, "Salad"
.to_string(), < ASalad < C > > ::declaration()), (3u8 as i64, "Sausage"
.to_string(), < ASausage < W > > ::declaration())
],
};
borsh::schema::add_definition(Self::declaration(), definition, definitions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ where
let definition = borsh::schema::Definition::Enum {
tag_width: 1,
variants: borsh::__private::maybestd::vec![
("Bacon".to_string(), < ABacon > ::declaration()), ("Eggs".to_string(), <
AEggs > ::declaration()), ("Salad".to_string(), < ASalad < C > >
::declaration()), ("Sausage".to_string(), < ASausage < W, U > >
::declaration())
(0u8 as i64, "Bacon".to_string(), < ABacon > ::declaration()), (1u8 as
i64, "Eggs".to_string(), < AEggs > ::declaration()), (2u8 as i64, "Salad"
.to_string(), < ASalad < C > > ::declaration()), (3u8 as i64, "Sausage"
.to_string(), < ASausage < W, U > > ::declaration())
],
};
borsh::schema::add_definition(Self::declaration(), definition, definitions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ where
let definition = borsh::schema::Definition::Enum {
tag_width: 1,
variants: borsh::__private::maybestd::vec![
("Bacon".to_string(), < ABacon > ::declaration()), ("Eggs".to_string(), <
AEggs > ::declaration()), ("Salad".to_string(), < ASalad < C > >
::declaration()), ("Sausage".to_string(), < ASausage < W > >
::declaration())
(0u8 as i64, "Bacon".to_string(), < ABacon > ::declaration()), (1u8 as
i64, "Eggs".to_string(), < AEggs > ::declaration()), (2u8 as i64, "Salad"
.to_string(), < ASalad < C > > ::declaration()), (3u8 as i64, "Sausage"
.to_string(), < ASausage < W > > ::declaration())
],
};
borsh::schema::add_definition(Self::declaration(), definition, definitions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ impl borsh::BorshSchema for A {
let definition = borsh::schema::Definition::Enum {
tag_width: 1,
variants: borsh::__private::maybestd::vec![
("B".to_string(), < AB > ::declaration()), ("Negative".to_string(), <
ANegative > ::declaration())
(0u8 as i64, "B".to_string(), < AB > ::declaration()), (1u8 as i64,
"Negative".to_string(), < ANegative > ::declaration())
],
};
borsh::schema::add_definition(Self::declaration(), definition, definitions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,9 @@ where
let definition = borsh::schema::Definition::Enum {
tag_width: 1,
variants: borsh::__private::maybestd::vec![
("B".to_string(), < EnumParametrizedB < K, V > > ::declaration()), ("C"
.to_string(), < EnumParametrizedC < T > > ::declaration())
(0u8 as i64, "B".to_string(), < EnumParametrizedB < K, V > >
::declaration()), (1u8 as i64, "C".to_string(), < EnumParametrizedC < T >
> ::declaration())
],
};
borsh::schema::add_definition(Self::declaration(), definition, definitions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,9 @@ where
let definition = borsh::schema::Definition::Enum {
tag_width: 1,
variants: borsh::__private::maybestd::vec![
("B".to_string(), < EnumParametrizedB < K, V > > ::declaration()), ("C"
.to_string(), < EnumParametrizedC < T > > ::declaration())
(0u8 as i64, "B".to_string(), < EnumParametrizedB < K, V > >
::declaration()), (1u8 as i64, "C".to_string(), < EnumParametrizedC < T >
> ::declaration())
],
};
borsh::schema::add_definition(Self::declaration(), definition, definitions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ where
let definition = borsh::schema::Definition::Enum {
tag_width: 1,
variants: borsh::__private::maybestd::vec![
("B".to_string(), < AB < K, V > > ::declaration()), ("C".to_string(), <
AC < K > > ::declaration())
(0u8 as i64, "B".to_string(), < AB < K, V > > ::declaration()), (1u8 as
i64, "C".to_string(), < AC < K > > ::declaration())
],
};
borsh::schema::add_definition(Self::declaration(), definition, definitions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ impl borsh::BorshSchema for A {
let definition = borsh::schema::Definition::Enum {
tag_width: 1,
variants: borsh::__private::maybestd::vec![
("Bacon".to_string(), < ABacon > ::declaration()), ("Eggs".to_string(), <
AEggs > ::declaration())
(0u8 as i64, "Bacon".to_string(), < ABacon > ::declaration()), (1u8 as
i64, "Eggs".to_string(), < AEggs > ::declaration())
],
};
borsh::schema::add_definition(Self::declaration(), definition, definitions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ impl reexporter::borsh::BorshSchema for A {
let definition = reexporter::borsh::schema::Definition::Enum {
tag_width: 1,
variants: reexporter::borsh::__private::maybestd::vec![
("Bacon".to_string(), < ABacon > ::declaration()), ("Eggs".to_string(), <
AEggs > ::declaration())
(0u8 as i64, "Bacon".to_string(), < ABacon > ::declaration()), (1u8 as
i64, "Eggs".to_string(), < AEggs > ::declaration())
],
};
reexporter::borsh::schema::add_definition(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ impl borsh::BorshSchema for A {
let definition = borsh::schema::Definition::Enum {
tag_width: 1,
variants: borsh::__private::maybestd::vec![
("Bacon".to_string(), < ABacon > ::declaration())
(0u8 as i64, "Bacon".to_string(), < ABacon > ::declaration())
],
};
borsh::schema::add_definition(Self::declaration(), definition, definitions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ where
let definition = borsh::schema::Definition::Enum {
tag_width: 1,
variants: borsh::__private::maybestd::vec![
("Left".to_string(), < SideLeft < A > > ::declaration()), ("Right"
.to_string(), < SideRight < B > > ::declaration())
(0u8 as i64, "Left".to_string(), < SideLeft < A > > ::declaration()),
(1u8 as i64, "Right".to_string(), < SideRight < B > > ::declaration())
],
};
borsh::schema::add_definition(Self::declaration(), definition, definitions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ where
let definition = borsh::schema::Definition::Enum {
tag_width: 1,
variants: borsh::__private::maybestd::vec![
("C3".to_string(), < CC3 > ::declaration()), ("C4".to_string(), < CC4 <
K, V > > ::declaration())
(0u8 as i64, "C3".to_string(), < CC3 > ::declaration()), (1u8 as i64,
"C4".to_string(), < CC4 < K, V > > ::declaration())
],
};
borsh::schema::add_definition(Self::declaration(), definition, definitions);
Expand Down
3 changes: 2 additions & 1 deletion borsh-derive/src/internals/serialize/enums/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ pub fn process(input: &ItemEnum, cratename: Path) -> syn::Result<TokenStream2> {

for (variant_idx, variant) in input.variants.iter().enumerate() {
let variant_ident = &variant.ident;
let discriminant_value = discriminants.get(variant_ident, use_discriminant, variant_idx)?;
let discriminant_value =
discriminants.get(variant_ident, use_discriminant, variant_idx, false)?;
let variant_output = process_variant(
variant,
enum_ident,
Expand Down
24 changes: 13 additions & 11 deletions borsh/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ pub use container_ext::{SchemaContainerValidateError, SchemaMaxSerializedSizeErr
pub type Declaration = String;
/// The type that we use for the name of the variant.
pub type VariantName = String;
/// The type that we use for value of discriminant.
pub type DiscriminantValue = i64;
/// The name of the field in the struct (can be used to convert JSON to Borsh using the schema).
pub type FieldName = String;
/// The type that we use to represent the definition of the Borsh type.
Expand Down Expand Up @@ -119,7 +121,7 @@ pub enum Definition {
tag_width: u8,

/// Possible variants of the enumeration.
variants: Vec<(VariantName, Declaration)>,
variants: Vec<(DiscriminantValue, VariantName, Declaration)>,
},

/// A structure, structurally similar to a tuple.
Expand Down Expand Up @@ -453,8 +455,8 @@ where
let definition = Definition::Enum {
tag_width: 1,
variants: vec![
("None".to_string(), <()>::declaration()),
("Some".to_string(), T::declaration()),
(0u8 as i64, "None".to_string(), <()>::declaration()),
(1u8 as i64, "Some".to_string(), T::declaration()),
],
};
add_definition(Self::declaration(), definition, definitions);
Expand All @@ -476,8 +478,8 @@ where
let definition = Definition::Enum {
tag_width: 1,
variants: vec![
("Ok".to_string(), T::declaration()),
("Err".to_string(), E::declaration()),
(1u8 as i64, "Ok".to_string(), T::declaration()),
(0u8 as i64, "Err".to_string(), E::declaration()),
],
};
add_definition(Self::declaration(), definition, definitions);
Expand Down Expand Up @@ -713,8 +715,8 @@ mod tests {
"Option<u64>" => Definition::Enum {
tag_width: 1,
variants: vec![
("None".to_string(), "nil".to_string()),
("Some".to_string(), "u64".to_string()),
(0, "None".to_string(), "nil".to_string()),
(1, "Some".to_string(), "u64".to_string()),
]
},
"u64" => Definition::Primitive(8),
Expand All @@ -735,15 +737,15 @@ mod tests {
"Option<u64>" => Definition::Enum {
tag_width: 1,
variants: vec![
("None".to_string(), "nil".to_string()),
("Some".to_string(), "u64".to_string()),
(0, "None".to_string(), "nil".to_string()),
(1, "Some".to_string(), "u64".to_string()),
]
},
"Option<Option<u64>>" => Definition::Enum {
tag_width: 1,
variants: vec![
("None".to_string(), "nil".to_string()),
("Some".to_string(), "Option<u64>".to_string()),
(0, "None".to_string(), "nil".to_string()),
(1, "Some".to_string(), "Option<u64>".to_string()),
]
},
"u64" => Definition::Primitive(8),
Expand Down
8 changes: 4 additions & 4 deletions borsh/src/schema/container_ext/max_size.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ fn max_serialized_size_impl<'a>(
variants,
}) => {
let mut max = 0;
for (_, variant) in variants {
for (_, _, variant) in variants {
let sz = max_serialized_size_impl(ONE, variant, schema, stack)?;
max = max.max(sz);
}
Expand Down Expand Up @@ -242,7 +242,7 @@ fn is_zero_size_impl<'a>(
variants,
}) => all(
variants.iter(),
|(_variant_name, declaration)| declaration,
|(_variant_discrim, _variant_name, declaration)| declaration,
schema,
stack,
)?,
Expand Down Expand Up @@ -449,8 +449,8 @@ mod tests {
let definition = Definition::Enum {
tag_width: N,
variants: vec![
("Just".into(), T::declaration()),
("Nothing".into(), "nil".into()),
(0, "Just".into(), T::declaration()),
(1, "Nothing".into(), "nil".into()),
],
};
crate::schema::add_definition(Self::declaration(), definition, definitions);
Expand Down
2 changes: 1 addition & 1 deletion borsh/src/schema/container_ext/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ fn validate_impl<'a>(
if *tag_width > U64_LEN {
return Err(Error::TagTooWide(declaration.to_string()));
}
for (_, variant) in variants {
for (_, _, variant) in variants {
validate_impl(variant, schema, stack)?;
}
}
Expand Down
Loading

0 comments on commit ab9add0

Please sign in to comment.