diff --git a/.github/test.sh b/.github/test.sh index 6a11ce20e..083c301a1 100755 --- a/.github/test.sh +++ b/.github/test.sh @@ -16,4 +16,5 @@ cargo test --no-default-features --features derive,schema cargo test --no-default-features --test test_rc --features rc cargo test --no-default-features --features hashbrown popd -cargo test --workspace +pushd borsh-derive +cargo test --features schema \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 8c2100c9f..47278a6ff 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,12 +1,5 @@ [workspace] -members = [ - "borsh", - "borsh-derive", - "borsh-derive-internal", - "borsh-schema-derive-internal", - "fuzz/fuzz-run", - "benchmarks", -] +members = ["borsh", "borsh-derive", "fuzz/fuzz-run", "benchmarks"] [workspace.package] # shared version of all public crates in the workspace diff --git a/borsh-derive-internal/Cargo.toml b/borsh-derive-internal/Cargo.toml deleted file mode 100644 index 015103024..000000000 --- a/borsh-derive-internal/Cargo.toml +++ /dev/null @@ -1,30 +0,0 @@ -[package] -name = "borsh-derive-internal" -version.workspace = true -rust-version.workspace = true -authors = ["Near Inc "] -edition = "2018" -license = "Apache-2.0" -readme = "README.md" -categories = ["encoding", "network-programming"] -repository = "https://github.com/nearprotocol/borsh" -homepage = "https://borsh.io" -description = """ -Binary Object Representation Serializer for Hashing -""" - -[dependencies] -proc-macro2 = "1" -syn = { version = "2", features = ["full", "fold"] } -quote = "1" -syn_derive = "0.1.6" -once_cell = "1.18.0" - -[dev-dependencies] -syn = { version = "2", features = ["full", "fold", "parsing"] } -prettyplease = "0.2.9" -insta = "1.29.0" - -[features] -default = [] -force_exhaustive_checks = [] diff --git a/borsh-derive-internal/README.md b/borsh-derive-internal/README.md deleted file mode 120000 index 32d46ee88..000000000 --- a/borsh-derive-internal/README.md +++ /dev/null @@ -1 +0,0 @@ -../README.md \ No newline at end of file diff --git a/borsh-derive-internal/src/attribute_helpers/field/bounds.rs b/borsh-derive-internal/src/attribute_helpers/field/bounds.rs deleted file mode 100644 index 822a25757..000000000 --- a/borsh-derive-internal/src/attribute_helpers/field/bounds.rs +++ /dev/null @@ -1,55 +0,0 @@ -use std::collections::BTreeMap; - -use syn::{meta::ParseNestedMeta, WherePredicate}; - -use crate::attribute_helpers::{parsing::parse_lit_into_vec, Symbol, DESERIALIZE, SERIALIZE}; -use once_cell::sync::Lazy; - -pub(crate) enum Variants { - Serialize(Vec), - Deserialize(Vec), -} - -type ParseFn = dyn Fn(Symbol, Symbol, &ParseNestedMeta) -> syn::Result + Send + Sync; - -pub(crate) static BOUNDS_FIELD_PARSE_MAP: Lazy>> = Lazy::new(|| { - let mut m = BTreeMap::new(); - // assigning closure `let f = |args| {...};` and boxing closure `let f: Box = Box::new(f);` - // on 2 separate lines doesn't work - let f_serialize: Box = Box::new(|attr_name, meta_item_name, meta| { - parse_lit_into_vec::(attr_name, meta_item_name, meta) - .map(Variants::Serialize) - }); - let f_deserialize: Box = Box::new(|attr_name, meta_item_name, meta| { - parse_lit_into_vec::(attr_name, meta_item_name, meta) - .map(Variants::Deserialize) - }); - m.insert(SERIALIZE, f_serialize); - m.insert(DESERIALIZE, f_deserialize); - m -}); - -#[derive(Default)] -pub(crate) struct Bounds { - pub serialize: Option>, - pub deserialize: Option>, -} - -impl From> for Bounds { - fn from(mut map: BTreeMap) -> Self { - let serialize = map.remove(&SERIALIZE); - let deserialize = map.remove(&DESERIALIZE); - let serialize = serialize.map(|variant| match variant { - Variants::Serialize(ser) => ser, - _ => unreachable!("only one enum variant is expected to correspond to given map key"), - }); - let deserialize = deserialize.map(|variant| match variant { - Variants::Deserialize(de) => de, - _ => unreachable!("only one enum variant is expected to correspond to given map key"), - }); - Self { - serialize, - deserialize, - } - } -} diff --git a/borsh-derive-internal/src/attribute_helpers/field/schema/with_funcs.rs b/borsh-derive-internal/src/attribute_helpers/field/schema/with_funcs.rs deleted file mode 100644 index 600cd0585..000000000 --- a/borsh-derive-internal/src/attribute_helpers/field/schema/with_funcs.rs +++ /dev/null @@ -1,57 +0,0 @@ -use std::collections::BTreeMap; - -use once_cell::sync::Lazy; -use syn::meta::ParseNestedMeta; - -use crate::attribute_helpers::{parsing::parse_lit_into, Symbol, DECLARATION, DEFINITIONS}; - -pub(crate) enum Variants { - Declaration(syn::ExprPath), - Definitions(syn::ExprPath), -} - -type ParseFn = dyn Fn(Symbol, Symbol, &ParseNestedMeta) -> syn::Result + Send + Sync; - -pub(crate) static WITH_FUNCS_FIELD_PARSE_MAP: Lazy>> = - Lazy::new(|| { - let mut m = BTreeMap::new(); - // assigning closure `let f = |args| {...};` and boxing closure `let f: Box = Box::new(f);` - // on 2 separate lines doesn't work - let f_declaration: Box = Box::new(|attr_name, meta_item_name, meta| { - parse_lit_into::(attr_name, meta_item_name, meta) - .map(Variants::Declaration) - }); - - let f_definitions: Box = Box::new(|attr_name, meta_item_name, meta| { - parse_lit_into::(attr_name, meta_item_name, meta) - .map(Variants::Definitions) - }); - - m.insert(DECLARATION, f_declaration); - m.insert(DEFINITIONS, f_definitions); - m - }); - -pub(crate) struct WithFuncs { - pub declaration: Option, - pub definitions: Option, -} - -impl From> for WithFuncs { - fn from(mut map: BTreeMap) -> Self { - let declaration = map.remove(&DECLARATION); - let definitions = map.remove(&DEFINITIONS); - let declaration = declaration.map(|variant| match variant { - Variants::Declaration(declaration) => declaration, - _ => unreachable!("only one enum variant is expected to correspond to given map key"), - }); - let definitions = definitions.map(|variant| match variant { - Variants::Definitions(definitions) => definitions, - _ => unreachable!("only one enum variant is expected to correspond to given map key"), - }); - Self { - declaration, - definitions, - } - } -} diff --git a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__bounds_parsing1-2.snap b/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__bounds_parsing1-2.snap deleted file mode 100644 index fbf2816b3..000000000 --- a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__bounds_parsing1-2.snap +++ /dev/null @@ -1,7 +0,0 @@ ---- -source: borsh-derive-internal/src/attribute_helpers/field.rs -expression: debug_print_bounds(de) ---- -K : Hash + Ord -V : Eq + Ord - diff --git a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__bounds_parsing1.snap b/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__bounds_parsing1.snap deleted file mode 100644 index 12df9b5ce..000000000 --- a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__bounds_parsing1.snap +++ /dev/null @@ -1,7 +0,0 @@ ---- -source: borsh-derive-internal/src/attribute_helpers/field.rs -expression: debug_print_bounds(ser) ---- -K : Hash + Eq + Ord -V : Ord - diff --git a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__bounds_parsing2-2.snap b/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__bounds_parsing2-2.snap deleted file mode 100644 index 4a3d68d10..000000000 --- a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__bounds_parsing2-2.snap +++ /dev/null @@ -1,7 +0,0 @@ ---- -source: borsh-derive-internal/src/attribute_helpers/field.rs -expression: debug_print_bounds(de) ---- -K : Hash + Eq + borsh :: de :: BorshDeserialize -V : borsh :: de :: BorshDeserialize - diff --git a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__bounds_parsing2.snap b/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__bounds_parsing2.snap deleted file mode 100644 index aae638734..000000000 --- a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__bounds_parsing2.snap +++ /dev/null @@ -1,7 +0,0 @@ ---- -source: borsh-derive-internal/src/attribute_helpers/field.rs -expression: debug_print_bounds(ser) ---- -K : Hash + Eq + borsh :: ser :: BorshSerialize -V : borsh :: ser :: BorshSerialize - diff --git a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__bounds_parsing3.snap b/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__bounds_parsing3.snap deleted file mode 100644 index 4a3d68d10..000000000 --- a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__bounds_parsing3.snap +++ /dev/null @@ -1,7 +0,0 @@ ---- -source: borsh-derive-internal/src/attribute_helpers/field.rs -expression: debug_print_bounds(de) ---- -K : Hash + Eq + borsh :: de :: BorshDeserialize -V : borsh :: de :: BorshDeserialize - diff --git a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__bounds_parsing4.snap b/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__bounds_parsing4.snap deleted file mode 100644 index 96b334bf5..000000000 --- a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__bounds_parsing4.snap +++ /dev/null @@ -1,6 +0,0 @@ ---- -source: borsh-derive-internal/src/attribute_helpers/field.rs -expression: debug_print_bounds(de) ---- -K : Hash - diff --git a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__bounds_parsing_error2.snap b/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__bounds_parsing_error2.snap deleted file mode 100644 index c529bde78..000000000 --- a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__bounds_parsing_error2.snap +++ /dev/null @@ -1,7 +0,0 @@ ---- -source: borsh-derive-internal/src/attribute_helpers/field.rs -expression: err ---- -Error( - "expected `:`", -) diff --git a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__root_bounds_and_params_combined-2.snap b/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__root_bounds_and_params_combined-2.snap deleted file mode 100644 index b8a83aa54..000000000 --- a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__root_bounds_and_params_combined-2.snap +++ /dev/null @@ -1,7 +0,0 @@ ---- -source: borsh-derive-internal/src/attribute_helpers/field.rs -expression: debug_print_bounds(schema.params) ---- -T => < T as TraitName > :: Associated -V => Vec < V > - diff --git a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__root_bounds_and_params_combined-3.snap b/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__root_bounds_and_params_combined-3.snap deleted file mode 100644 index 0b2b40540..000000000 --- a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__root_bounds_and_params_combined-3.snap +++ /dev/null @@ -1,6 +0,0 @@ ---- -source: borsh-derive-internal/src/attribute_helpers/field.rs -expression: debug_print_tokenizable(attrs.serialize_with) ---- -third_party_impl :: serialize_third_party - diff --git a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__root_bounds_and_params_combined.snap b/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__root_bounds_and_params_combined.snap deleted file mode 100644 index 7c373e4a9..000000000 --- a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__root_bounds_and_params_combined.snap +++ /dev/null @@ -1,6 +0,0 @@ ---- -source: borsh-derive-internal/src/attribute_helpers/field.rs -expression: debug_print_bounds(bounds.deserialize) ---- -K : Hash - diff --git a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__schema_params_parsing1.snap b/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__schema_params_parsing1.snap deleted file mode 100644 index 5802e1663..000000000 --- a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__schema_params_parsing1.snap +++ /dev/null @@ -1,6 +0,0 @@ ---- -source: borsh-derive-internal/src/attribute_helpers/field.rs -expression: debug_print_bounds(schema_params) ---- -T => < T as TraitName > :: Associated - diff --git a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__schema_params_parsing2.snap b/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__schema_params_parsing2.snap deleted file mode 100644 index 941ba2100..000000000 --- a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__schema_params_parsing2.snap +++ /dev/null @@ -1,7 +0,0 @@ ---- -source: borsh-derive-internal/src/attribute_helpers/field.rs -expression: debug_print_bounds(schema_params) ---- -T => < T as TraitName > :: Associated -V => Vec < V > - diff --git a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__schema_params_parsing_error.snap b/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__schema_params_parsing_error.snap deleted file mode 100644 index 9336f5bb6..000000000 --- a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__schema_params_parsing_error.snap +++ /dev/null @@ -1,7 +0,0 @@ ---- -source: borsh-derive-internal/src/attribute_helpers/field.rs -expression: err ---- -Error( - "expected `>`", -) diff --git a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__schema_with_funcs_parsing.snap b/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__schema_with_funcs_parsing.snap deleted file mode 100644 index fa2cbac08..000000000 --- a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__schema_with_funcs_parsing.snap +++ /dev/null @@ -1,6 +0,0 @@ ---- -source: borsh-derive-internal/src/attribute_helpers/field.rs -expression: debug_print_tokenizable(with_funcs.declaration) ---- -third_party_impl :: declaration :: < K , V > - diff --git a/borsh-derive-internal/src/generics.rs b/borsh-derive-internal/src/generics.rs deleted file mode 100644 index 972de5b77..000000000 --- a/borsh-derive-internal/src/generics.rs +++ /dev/null @@ -1,306 +0,0 @@ -// TODO: remove this unused attribute, when the unsplit is done -#![allow(unused)] -use std::collections::{HashMap, HashSet}; - -use quote::{quote, ToTokens}; -use syn::{ - punctuated::Pair, Field, GenericArgument, Generics, Ident, Macro, Path, PathArguments, - PathSegment, ReturnType, Type, TypeParamBound, TypePath, WherePredicate, -}; - -pub fn compute_predicates(params: Vec, traitname: &Path) -> Vec { - params - .into_iter() - .map(|param| { - syn::parse2(quote! { - #param: #traitname - }) - .unwrap() - }) - .collect() -} - -// Remove the default from every type parameter because in the generated impls -// they look like associated types: "error: associated type bindings are not -// allowed here". -pub fn without_defaults(generics: &Generics) -> Generics { - syn::Generics { - params: generics - .params - .iter() - .map(|param| match param { - syn::GenericParam::Type(param) => syn::GenericParam::Type(syn::TypeParam { - eq_token: None, - default: None, - ..param.clone() - }), - _ => param.clone(), - }) - .collect(), - ..generics.clone() - } -} - -pub fn type_contains_some_param(type_: &Type, params: &HashSet) -> bool { - let mut find: FindTyParams = FindTyParams::from_params(params.iter()); - - find.visit_type_top_level(type_); - - find.at_least_one_hit() -} - -/// a Visitor-like struct, which helps determine, if a type parameter is found in field -#[derive(Clone)] -pub struct FindTyParams { - // Set of all generic type parameters on the current struct . Initialized up front. - all_type_params: HashSet, - all_type_params_ordered: Vec, - - // Set of generic type parameters used in fields for which filter - // returns true . Filled in as the visitor sees them. - relevant_type_params: HashSet, - - // [Param] => [Type, containing Param] mapping - associated_type_params_usage: HashMap>, -} - -fn ungroup(mut ty: &Type) -> &Type { - while let Type::Group(group) = ty { - ty = &group.elem; - } - ty -} - -impl FindTyParams { - pub fn new(generics: &Generics) -> Self { - let all_type_params = generics - .type_params() - .map(|param| param.ident.clone()) - .collect(); - - let all_type_params_ordered = generics - .type_params() - .map(|param| param.ident.clone()) - .collect(); - - FindTyParams { - all_type_params, - all_type_params_ordered, - relevant_type_params: HashSet::new(), - associated_type_params_usage: HashMap::new(), - } - } - pub fn from_params<'a>(params: impl Iterator) -> Self { - let all_type_params_ordered: Vec = params.cloned().collect(); - let all_type_params = all_type_params_ordered.clone().into_iter().collect(); - FindTyParams { - all_type_params, - all_type_params_ordered, - relevant_type_params: HashSet::new(), - associated_type_params_usage: HashMap::new(), - } - } - pub fn process_for_bounds(self) -> Vec { - let relevant_type_params = self.relevant_type_params; - let associated_type_params_usage = self.associated_type_params_usage; - let mut new_predicates: Vec = vec![]; - let mut new_predicates_set: HashSet = HashSet::new(); - - self.all_type_params_ordered.iter().for_each(|param| { - if relevant_type_params.contains(param) { - let ty = Type::Path(TypePath { - qself: None, - path: param.clone().into(), - }); - let ty_str_repr = ty.to_token_stream().to_string(); - if !new_predicates_set.contains(&ty_str_repr) { - new_predicates.push(ty); - new_predicates_set.insert(ty_str_repr); - } - } - if let Some(vec_type) = associated_type_params_usage.get(param) { - for type_ in vec_type { - let ty_str_repr = type_.to_token_stream().to_string(); - if !new_predicates_set.contains(&ty_str_repr) { - new_predicates.push(type_.clone()); - new_predicates_set.insert(ty_str_repr); - } - } - } - }); - - new_predicates - } - pub fn process_for_params(self) -> Vec { - let relevant_type_params = self.relevant_type_params; - let associated_type_params_usage = self.associated_type_params_usage; - - let mut params: Vec = vec![]; - let mut params_set: HashSet = HashSet::new(); - self.all_type_params_ordered.iter().for_each(|param| { - if relevant_type_params.contains(param) && !params_set.contains(param) { - params.push(param.clone()); - params_set.insert(param.clone()); - } - if associated_type_params_usage.get(param).is_some() && !params_set.contains(param) { - params.push(param.clone()); - params_set.insert(param.clone()); - } - }); - params - } - pub fn at_least_one_hit(&self) -> bool { - !self.relevant_type_params.is_empty() || !self.associated_type_params_usage.is_empty() - } -} - -impl FindTyParams { - pub fn visit_field(&mut self, field: &Field) { - self.visit_type_top_level(&field.ty); - } - - pub fn visit_type_top_level(&mut self, type_: &Type) { - if let Type::Path(ty) = ungroup(type_) { - if let Some(Pair::Punctuated(t, _)) = ty.path.segments.pairs().next() { - if self.all_type_params.contains(&t.ident) { - self.param_associated_type_insert(t.ident.clone(), type_.clone()); - } - } - } - self.visit_type(type_); - } - - pub fn param_associated_type_insert(&mut self, param: Ident, type_: Type) { - if let Some(type_vec) = self.associated_type_params_usage.get_mut(¶m) { - type_vec.push(type_); - } else { - let type_vec = vec![type_]; - self.associated_type_params_usage.insert(param, type_vec); - } - } - - fn visit_return_type(&mut self, return_type: &ReturnType) { - match return_type { - ReturnType::Default => {} - ReturnType::Type(_, output) => self.visit_type(output), - } - } - - fn visit_path_segment(&mut self, segment: &PathSegment) { - self.visit_path_arguments(&segment.arguments); - } - - fn visit_path_arguments(&mut self, arguments: &PathArguments) { - match arguments { - PathArguments::None => {} - PathArguments::AngleBracketed(arguments) => { - for arg in &arguments.args { - match arg { - GenericArgument::Type(arg) => self.visit_type(arg), - GenericArgument::AssocType(arg) => self.visit_type(&arg.ty), - GenericArgument::Lifetime(_) - | GenericArgument::Const(_) - | GenericArgument::AssocConst(_) - | GenericArgument::Constraint(_) => {} - #[cfg_attr( - feature = "force_exhaustive_checks", - deny(non_exhaustive_omitted_patterns) - )] - _ => {} - } - } - } - PathArguments::Parenthesized(arguments) => { - for argument in &arguments.inputs { - self.visit_type(argument); - } - self.visit_return_type(&arguments.output); - } - } - } - - fn visit_path(&mut self, path: &Path) { - if let Some(seg) = path.segments.last() { - if seg.ident == "PhantomData" { - // Hardcoded exception, because PhantomData implements - // Serialize and Deserialize and Schema whether or not T implements it. - return; - } - } - if path.leading_colon.is_none() && path.segments.len() == 1 { - let id = &path.segments[0].ident; - if self.all_type_params.contains(id) { - self.relevant_type_params.insert(id.clone()); - } - } - for segment in &path.segments { - self.visit_path_segment(segment); - } - } - - fn visit_type_param_bound(&mut self, bound: &TypeParamBound) { - match bound { - TypeParamBound::Trait(bound) => self.visit_path(&bound.path), - TypeParamBound::Lifetime(_) | TypeParamBound::Verbatim(_) => {} - #[cfg_attr( - feature = "force_exhaustive_checks", - deny(non_exhaustive_omitted_patterns) - )] - _ => {} - } - } - // Type parameter should not be considered used by a macro path. - // - // struct TypeMacro { - // mac: T!(), - // marker: PhantomData, - // } - fn visit_macro(&mut self, _mac: &Macro) {} - - fn visit_type(&mut self, ty: &Type) { - match ty { - Type::Array(ty) => self.visit_type(&ty.elem), - Type::BareFn(ty) => { - for arg in &ty.inputs { - self.visit_type(&arg.ty); - } - self.visit_return_type(&ty.output); - } - Type::Group(ty) => self.visit_type(&ty.elem), - Type::ImplTrait(ty) => { - for bound in &ty.bounds { - self.visit_type_param_bound(bound); - } - } - Type::Macro(ty) => self.visit_macro(&ty.mac), - Type::Paren(ty) => self.visit_type(&ty.elem), - Type::Path(ty) => { - if let Some(qself) = &ty.qself { - self.visit_type(&qself.ty); - } - self.visit_path(&ty.path); - } - Type::Ptr(ty) => self.visit_type(&ty.elem), - Type::Reference(ty) => self.visit_type(&ty.elem), - Type::Slice(ty) => self.visit_type(&ty.elem), - Type::TraitObject(ty) => { - for bound in &ty.bounds { - self.visit_type_param_bound(bound); - } - } - Type::Tuple(ty) => { - for elem in &ty.elems { - self.visit_type(elem); - } - } - - Type::Infer(_) | Type::Never(_) | Type::Verbatim(_) => {} - - #[cfg_attr( - feature = "force_exhaustive_checks", - deny(non_exhaustive_omitted_patterns) - )] - _ => {} - } - } -} diff --git a/borsh-derive-internal/src/lib.rs b/borsh-derive-internal/src/lib.rs deleted file mode 100644 index d420fc938..000000000 --- a/borsh-derive-internal/src/lib.rs +++ /dev/null @@ -1,26 +0,0 @@ -#![recursion_limit = "128"] -#![cfg_attr( - feature = "force_exhaustive_checks", - feature(non_exhaustive_omitted_patterns_lint) -)] - -pub mod attribute_helpers; -mod enum_de; -mod enum_discriminant_map; -mod enum_ser; -mod generics; -mod struct_de; -mod struct_ser; -mod union_de; -mod union_ser; - -pub use enum_de::enum_de; -pub use enum_ser::enum_ser; -pub use struct_de::struct_de; -pub use struct_ser::struct_ser; -pub use union_de::union_de; -pub use union_ser::union_ser; - -pub use attribute_helpers::check_item_attributes; -#[cfg(test)] -pub mod test_helpers; diff --git a/borsh-derive-internal/src/test_helpers.rs b/borsh-derive-internal/src/test_helpers.rs deleted file mode 100644 index 6c4d17a3d..000000000 --- a/borsh-derive-internal/src/test_helpers.rs +++ /dev/null @@ -1,9 +0,0 @@ -use proc_macro2::TokenStream; -use quote::quote; - -pub fn pretty_print_syn_str(input: &TokenStream) -> syn::Result { - let input = format!("{}", quote!(#input)); - let syn_file = syn::parse_str::(&input)?; - - Ok(prettyplease::unparse(&syn_file)) -} diff --git a/borsh-derive/Cargo.toml b/borsh-derive/Cargo.toml index c514b27eb..e818da91d 100644 --- a/borsh-derive/Cargo.toml +++ b/borsh-derive/Cargo.toml @@ -17,13 +17,24 @@ Binary Object Representation Serializer for Hashing proc-macro = true [dependencies] -borsh-derive-internal = { path = "../borsh-derive-internal", version = "0.11.0" } -borsh-schema-derive-internal = { path = "../borsh-schema-derive-internal", version = "0.11.0", optional = true } syn = { version = "2", features = ["full", "fold"] } proc-macro-crate = "1" proc-macro2 = "1" quote = "1" +once_cell = "1.18.0" +syn_derive = "0.1.6" + +[dev-dependencies] +syn = { version = "2", features = ["full", "fold", "parsing"] } +prettyplease = "0.2.9" +insta = "1.29.0" + + +[package.metadata.docs.rs] +features = ["schema"] +targets = ["x86_64-unknown-linux-gnu"] [features] default = [] -schema = ["borsh-schema-derive-internal"] +schema = [] +force_exhaustive_checks = [] diff --git a/borsh-schema-derive-internal/src/attribute_helpers/field/bounds.rs b/borsh-derive/src/internals/attributes/field/bounds.rs similarity index 87% rename from borsh-schema-derive-internal/src/attribute_helpers/field/bounds.rs rename to borsh-derive/src/internals/attributes/field/bounds.rs index 822a25757..d383b2327 100644 --- a/borsh-schema-derive-internal/src/attribute_helpers/field/bounds.rs +++ b/borsh-derive/src/internals/attributes/field/bounds.rs @@ -2,17 +2,17 @@ use std::collections::BTreeMap; use syn::{meta::ParseNestedMeta, WherePredicate}; -use crate::attribute_helpers::{parsing::parse_lit_into_vec, Symbol, DESERIALIZE, SERIALIZE}; +use crate::internals::attributes::{parsing::parse_lit_into_vec, Symbol, DESERIALIZE, SERIALIZE}; use once_cell::sync::Lazy; -pub(crate) enum Variants { +pub enum Variants { Serialize(Vec), Deserialize(Vec), } type ParseFn = dyn Fn(Symbol, Symbol, &ParseNestedMeta) -> syn::Result + Send + Sync; -pub(crate) static BOUNDS_FIELD_PARSE_MAP: Lazy>> = Lazy::new(|| { +pub static BOUNDS_FIELD_PARSE_MAP: Lazy>> = Lazy::new(|| { let mut m = BTreeMap::new(); // assigning closure `let f = |args| {...};` and boxing closure `let f: Box = Box::new(f);` // on 2 separate lines doesn't work @@ -29,8 +29,8 @@ pub(crate) static BOUNDS_FIELD_PARSE_MAP: Lazy>> = m }); -#[derive(Default)] -pub(crate) struct Bounds { +#[derive(Default, Clone)] +pub struct Bounds { pub serialize: Option>, pub deserialize: Option>, } diff --git a/borsh-derive-internal/src/attribute_helpers/field.rs b/borsh-derive/src/internals/attributes/field/mod.rs similarity index 81% rename from borsh-derive-internal/src/attribute_helpers/field.rs rename to borsh-derive/src/internals/attributes/field/mod.rs index a786be374..485561b89 100644 --- a/borsh-derive-internal/src/attribute_helpers/field.rs +++ b/borsh-derive/src/internals/attributes/field/mod.rs @@ -1,26 +1,31 @@ -#![allow(unused)] -// TODO: remove unused when unsplit is done use std::collections::BTreeMap; use once_cell::sync::Lazy; -use syn::{meta::ParseNestedMeta, Attribute, ExprPath, WherePredicate}; +use syn::{meta::ParseNestedMeta, Attribute, WherePredicate}; -use self::{bounds::BOUNDS_FIELD_PARSE_MAP, schema::SCHEMA_FIELD_PARSE_MAP}; +use self::bounds::BOUNDS_FIELD_PARSE_MAP; use super::{ parsing::{attr_get_by_symbol_keys, meta_get_by_symbol_keys, parse_lit_into}, - BoundType, Symbol, BORSH, BOUND, DESERIALIZE_WITH, PARAMS, SCHEMA, SERIALIZE_WITH, SKIP, - WITH_FUNCS, + BoundType, Symbol, BORSH, BOUND, DESERIALIZE_WITH, SERIALIZE_WITH, SKIP, +}; + +#[cfg(feature = "schema")] +use { + super::schema_keys::{PARAMS, SCHEMA, WITH_FUNCS}, + schema::SCHEMA_FIELD_PARSE_MAP, }; pub mod bounds; +#[cfg(feature = "schema")] pub mod schema; enum Variants { - Schema(schema::Attributes), Bounds(bounds::Bounds), SerializeWith(syn::ExprPath), DeserializeWith(syn::ExprPath), + #[cfg(feature = "schema")] + Schema(schema::Attributes), } type ParseFn = dyn Fn(Symbol, Symbol, &ParseNestedMeta) -> syn::Result + Send + Sync; @@ -35,12 +40,6 @@ static BORSH_FIELD_PARSE_MAP: Lazy>> = Lazy::new(| Ok(Variants::Bounds(bounds_attributes)) }); - let f_schema: Box = Box::new(|_attr_name, _meta_item_name, meta| { - let map_result = meta_get_by_symbol_keys(SCHEMA, meta, &SCHEMA_FIELD_PARSE_MAP)?; - let schema_attributes: schema::Attributes = map_result.into(); - Ok(Variants::Schema(schema_attributes)) - }); - let f_serialize_with: Box = Box::new(|attr_name, meta_item_name, meta| { parse_lit_into::(attr_name, meta_item_name, meta) .map(Variants::SerializeWith) @@ -51,35 +50,39 @@ static BORSH_FIELD_PARSE_MAP: Lazy>> = Lazy::new(| .map(Variants::DeserializeWith) }); + #[cfg(feature = "schema")] + let f_schema: Box = Box::new(|_attr_name, _meta_item_name, meta| { + let map_result = meta_get_by_symbol_keys(SCHEMA, meta, &SCHEMA_FIELD_PARSE_MAP)?; + let schema_attributes: schema::Attributes = map_result.into(); + Ok(Variants::Schema(schema_attributes)) + }); + m.insert(BOUND, f_bounds); - m.insert(SCHEMA, f_schema); m.insert(SERIALIZE_WITH, f_serialize_with); m.insert(DESERIALIZE_WITH, f_deserialize_with); + #[cfg(feature = "schema")] + m.insert(SCHEMA, f_schema); m }); -#[derive(Default)] +#[derive(Default, Clone)] pub(crate) struct Attributes { pub bounds: Option, - pub schema: Option, pub serialize_with: Option, pub deserialize_with: Option, + #[cfg(feature = "schema")] + pub schema: Option, } impl From> for Attributes { fn from(mut map: BTreeMap) -> Self { let bounds = map.remove(&BOUND); - let schema = map.remove(&SCHEMA); let serialize_with = map.remove(&SERIALIZE_WITH); let deserialize_with = map.remove(&DESERIALIZE_WITH); let bounds = bounds.map(|variant| match variant { Variants::Bounds(bounds) => bounds, _ => unreachable!("only one enum variant is expected to correspond to given map key"), }); - let schema = schema.map(|variant| match variant { - Variants::Schema(schema) => schema, - _ => unreachable!("only one enum variant is expected to correspond to given map key"), - }); let serialize_with = serialize_with.map(|variant| match variant { Variants::SerializeWith(serialize_with) => serialize_with, @@ -90,14 +93,38 @@ impl From> for Attributes { Variants::DeserializeWith(deserialize_with) => deserialize_with, _ => unreachable!("only one enum variant is expected to correspond to given map key"), }); + + #[cfg(feature = "schema")] + let schema = { + let schema = map.remove(&SCHEMA); + schema.map(|variant| match variant { + Variants::Schema(schema) => schema, + _ => { + unreachable!("only one enum variant is expected to correspond to given map key") + } + }) + }; Self { bounds, - schema, serialize_with, deserialize_with, + #[cfg(feature = "schema")] + schema, } } } + +pub(crate) fn contains_skip(attrs: &[Attribute]) -> bool { + attrs.iter().any(|attr| attr.path() == SKIP) +} + +#[cfg(feature = "schema")] +pub(crate) fn filter_attrs( + attrs: impl Iterator, +) -> impl Iterator { + attrs.filter(|attr| attr.path() == SKIP || attr.path() == BORSH) +} + impl Attributes { fn check(&self, skipped: bool, attr: &Attribute) -> Result<(), syn::Error> { if skipped && (self.serialize_with.is_some() || self.deserialize_with.is_some()) { @@ -109,6 +136,46 @@ impl Attributes { ), )); } + + #[cfg(feature = "schema")] + self.check_schema(skipped, attr)?; + + Ok(()) + } + pub(crate) fn parse(attrs: &[Attribute], skipped: bool) -> Result { + let attr = attrs.iter().find(|attr| attr.path() == BORSH); + + let result: Self = if let Some(attr) = attr { + let result: Self = attr_get_by_symbol_keys(BORSH, attr, &BORSH_FIELD_PARSE_MAP)?.into(); + result.check(skipped, attr)?; + result + } else { + BTreeMap::new().into() + }; + + Ok(result) + } + pub(crate) fn needs_bounds_derive(&self, ty: BoundType) -> bool { + let predicates = self.get_bounds(ty); + predicates.is_none() + } + + fn get_bounds(&self, ty: BoundType) -> Option> { + let bounds = self.bounds.as_ref(); + bounds.and_then(|bounds| match ty { + BoundType::Serialize => bounds.serialize.clone(), + BoundType::Deserialize => bounds.deserialize.clone(), + }) + } + pub(crate) fn collect_bounds(&self, ty: BoundType) -> Vec { + let predicates = self.get_bounds(ty); + predicates.unwrap_or(vec![]) + } +} + +#[cfg(feature = "schema")] +impl Attributes { + fn check_schema(&self, skipped: bool, attr: &Attribute) -> Result<(), syn::Error> { if let Some(ref schema) = self.schema { if skipped && schema.params.is_some() { return Err(syn::Error::new_spanned( @@ -132,23 +199,6 @@ impl Attributes { } Ok(()) } - pub(crate) fn parse(attrs: &[Attribute], skipped: bool) -> Result { - let attr = attrs.iter().find(|attr| attr.path() == BORSH); - - let result: Self = if let Some(attr) = attr { - let result: Self = attr_get_by_symbol_keys(BORSH, attr, &BORSH_FIELD_PARSE_MAP)?.into(); - result.check(skipped, attr)?; - result - } else { - BTreeMap::new().into() - }; - - Ok(result) - } - pub(crate) fn needs_bounds_derive(&self, ty: BoundType) -> bool { - let predicates = self.get_bounds(ty); - predicates.is_none() - } pub(crate) fn needs_schema_params_derive(&self) -> bool { if let Some(ref schema) = self.schema { @@ -158,7 +208,8 @@ impl Attributes { } true } - pub(crate) fn schema_declaration(&self) -> Option { + + pub(crate) fn schema_declaration(&self) -> Option { self.schema.as_ref().and_then(|schema| { schema .with_funcs @@ -167,7 +218,7 @@ impl Attributes { }) } - pub(crate) fn schema_definitions(&self) -> Option { + pub(crate) fn schema_definitions(&self) -> Option { self.schema.as_ref().and_then(|schema| { schema .with_funcs @@ -175,24 +226,11 @@ impl Attributes { .and_then(|with_funcs| with_funcs.definitions.clone()) }) } - - fn get_bounds(&self, ty: BoundType) -> Option> { - let bounds = self.bounds.as_ref(); - bounds.and_then(|bounds| match ty { - BoundType::Serialize => bounds.serialize.clone(), - BoundType::Deserialize => bounds.deserialize.clone(), - }) - } - pub(crate) fn collect_bounds(&self, ty: BoundType) -> Vec { - let predicates = self.get_bounds(ty); - predicates.unwrap_or(vec![]) - } } #[cfg(test)] mod tests { - use quote::{quote, ToTokens}; - use std::fmt::Write; + use quote::quote; use syn::{Attribute, ItemStruct}; fn parse_bounds(attrs: &[Attribute]) -> Result, syn::Error> { @@ -201,53 +239,12 @@ mod tests { Ok(borsh_attrs.bounds) } - fn parse_schema_attrs(attrs: &[Attribute]) -> Result, syn::Error> { - // #[borsh(schema(params = "..."))] - let borsh_attrs = Attributes::parse(attrs, false)?; - Ok(borsh_attrs.schema) - } + use crate::internals::test_helpers::{ + debug_print_tokenizable, debug_print_vec_of_tokenizable, local_insta_assert_debug_snapshot, + local_insta_assert_snapshot, + }; - use super::{bounds, schema, Attributes}; - fn debug_print_vec_of_tokenizable(optional: Option>) -> String { - let mut s = String::new(); - if let Some(vec) = optional { - for element in vec { - writeln!(&mut s, "{}", element.to_token_stream()).unwrap(); - } - } else { - write!(&mut s, "None").unwrap(); - } - s - } - - fn debug_print_tokenizable(optional: Option) -> String { - let mut s = String::new(); - if let Some(type_) = optional { - writeln!(&mut s, "{}", type_.to_token_stream()).unwrap(); - } else { - write!(&mut s, "None").unwrap(); - } - s - } - - #[test] - fn test_root_error() { - let item_struct: ItemStruct = syn::parse2(quote! { - struct A { - #[borsh(boons)] - x: u64, - y: String, - } - }) - .unwrap(); - - let first_field = &item_struct.fields.into_iter().collect::>()[0]; - let err = match Attributes::parse(&first_field.attrs, false) { - Ok(..) => unreachable!("expecting error here"), - Err(err) => err, - }; - insta::assert_debug_snapshot!(err); - } + use super::{bounds, Attributes}; #[test] fn test_bounds_parsing1() { @@ -266,8 +263,8 @@ mod tests { let first_field = &item_struct.fields.into_iter().collect::>()[0]; let attrs = parse_bounds(&first_field.attrs).unwrap().unwrap(); - insta::assert_snapshot!(debug_print_vec_of_tokenizable(attrs.serialize)); - insta::assert_snapshot!(debug_print_vec_of_tokenizable(attrs.deserialize)); + local_insta_assert_snapshot!(debug_print_vec_of_tokenizable(attrs.serialize.clone())); + local_insta_assert_snapshot!(debug_print_vec_of_tokenizable(attrs.deserialize)); } #[test] @@ -287,8 +284,8 @@ mod tests { let first_field = &item_struct.fields.into_iter().collect::>()[0]; let attrs = parse_bounds(&first_field.attrs).unwrap().unwrap(); - insta::assert_snapshot!(debug_print_vec_of_tokenizable(attrs.serialize)); - insta::assert_snapshot!(debug_print_vec_of_tokenizable(attrs.deserialize)); + local_insta_assert_snapshot!(debug_print_vec_of_tokenizable(attrs.serialize.clone())); + local_insta_assert_snapshot!(debug_print_vec_of_tokenizable(attrs.deserialize)); } #[test] @@ -307,8 +304,8 @@ mod tests { let first_field = &item_struct.fields.into_iter().collect::>()[0]; let attrs = parse_bounds(&first_field.attrs).unwrap().unwrap(); - assert_eq!(attrs.serialize.unwrap().len(), 0); - insta::assert_snapshot!(debug_print_vec_of_tokenizable(attrs.deserialize)); + assert_eq!(attrs.serialize.as_ref().unwrap().len(), 0); + local_insta_assert_snapshot!(debug_print_vec_of_tokenizable(attrs.deserialize)); } #[test] @@ -325,7 +322,7 @@ mod tests { let first_field = &item_struct.fields.into_iter().collect::>()[0]; let attrs = parse_bounds(&first_field.attrs).unwrap().unwrap(); assert!(attrs.serialize.is_none()); - insta::assert_snapshot!(debug_print_vec_of_tokenizable(attrs.deserialize)); + local_insta_assert_snapshot!(debug_print_vec_of_tokenizable(attrs.deserialize)); } #[test] @@ -344,7 +341,7 @@ mod tests { Ok(..) => unreachable!("expecting error here"), Err(err) => err, }; - insta::assert_debug_snapshot!(err); + local_insta_assert_debug_snapshot!(err); } #[test] @@ -363,7 +360,7 @@ mod tests { Ok(..) => unreachable!("expecting error here"), Err(err) => err, }; - insta::assert_debug_snapshot!(err); + local_insta_assert_debug_snapshot!(err); } #[test] @@ -382,7 +379,76 @@ mod tests { Ok(..) => unreachable!("expecting error here"), Err(err) => err, }; - insta::assert_debug_snapshot!(err); + local_insta_assert_debug_snapshot!(err); + } + + #[test] + fn test_ser_de_with_parsing1() { + let item_struct: ItemStruct = syn::parse2(quote! { + struct A { + #[borsh( + serialize_with = "third_party_impl::serialize_third_party", + deserialize_with = "third_party_impl::deserialize_third_party", + )] + x: u64, + y: String, + } + }) + .unwrap(); + + let first_field = &item_struct.fields.into_iter().collect::>()[0]; + let attrs = Attributes::parse(&first_field.attrs, false).unwrap(); + local_insta_assert_snapshot!(debug_print_tokenizable(attrs.serialize_with.as_ref())); + local_insta_assert_snapshot!(debug_print_tokenizable(attrs.deserialize_with)); + } +} + +#[cfg(feature = "schema")] +#[cfg(test)] +mod tests_schema { + use crate::internals::{ + attributes::field::Attributes, + test_helpers::{ + debug_print_tokenizable, debug_print_vec_of_tokenizable, + local_insta_assert_debug_snapshot, local_insta_assert_snapshot, + }, + }; + + use quote::quote; + use syn::{Attribute, ItemStruct}; + + use super::schema; + fn parse_schema_attrs(attrs: &[Attribute]) -> Result, syn::Error> { + // #[borsh(schema(params = "..."))] + let borsh_attrs = Attributes::parse(attrs, false)?; + Ok(borsh_attrs.schema) + } + + #[test] + fn test_root_bounds_and_params_combined() { + let item_struct: ItemStruct = syn::parse2(quote! { + struct A { + #[borsh( + serialize_with = "third_party_impl::serialize_third_party", + bound(deserialize = "K: Hash"), + schema(params = "T => ::Associated, V => Vec") + )] + x: u64, + y: String, + } + }) + .unwrap(); + + let first_field = &item_struct.fields.into_iter().collect::>()[0]; + + let attrs = Attributes::parse(&first_field.attrs, false).unwrap(); + let bounds = attrs.bounds.clone().unwrap(); + assert!(bounds.serialize.is_none()); + local_insta_assert_snapshot!(debug_print_vec_of_tokenizable(bounds.deserialize)); + assert!(attrs.deserialize_with.is_none()); + let schema = attrs.schema.clone().unwrap(); + local_insta_assert_snapshot!(debug_print_vec_of_tokenizable(schema.params.clone())); + local_insta_assert_snapshot!(debug_print_tokenizable(attrs.serialize_with)); } #[test] @@ -403,7 +469,7 @@ mod tests { let first_field = &item_struct.fields.into_iter().collect::>()[0]; let schema_attrs = parse_schema_attrs(&first_field.attrs).unwrap(); - insta::assert_snapshot!(debug_print_vec_of_tokenizable(schema_attrs.unwrap().params)); + local_insta_assert_snapshot!(debug_print_vec_of_tokenizable(schema_attrs.unwrap().params)); } #[test] fn test_schema_params_parsing_error() { @@ -426,7 +492,7 @@ mod tests { Ok(..) => unreachable!("expecting error here"), Err(err) => err, }; - insta::assert_debug_snapshot!(err); + local_insta_assert_debug_snapshot!(err); } #[test] @@ -450,7 +516,7 @@ mod tests { Ok(..) => unreachable!("expecting error here"), Err(err) => err, }; - insta::assert_debug_snapshot!(err); + local_insta_assert_debug_snapshot!(err); } #[test] @@ -471,7 +537,7 @@ mod tests { let first_field = &item_struct.fields.into_iter().collect::>()[0]; let schema_attrs = parse_schema_attrs(&first_field.attrs).unwrap(); - insta::assert_snapshot!(debug_print_vec_of_tokenizable(schema_attrs.unwrap().params)); + local_insta_assert_snapshot!(debug_print_vec_of_tokenizable(schema_attrs.unwrap().params)); } #[test] fn test_schema_params_parsing3() { @@ -510,26 +576,6 @@ mod tests { assert!(schema_attrs.is_none()); } - #[test] - fn test_ser_de_with_parsing1() { - let item_struct: ItemStruct = syn::parse2(quote! { - struct A { - #[borsh( - serialize_with = "third_party_impl::serialize_third_party", - deserialize_with = "third_party_impl::deserialize_third_party", - )] - x: u64, - y: String, - } - }) - .unwrap(); - - let first_field = &item_struct.fields.into_iter().collect::>()[0]; - let attrs = Attributes::parse(&first_field.attrs, false).unwrap(); - insta::assert_snapshot!(debug_print_tokenizable(attrs.serialize_with)); - insta::assert_snapshot!(debug_print_tokenizable(attrs.deserialize_with)); - } - #[test] fn test_schema_with_funcs_parsing() { let item_struct: ItemStruct = syn::parse2(quote! { @@ -549,8 +595,8 @@ mod tests { let schema = attrs.schema.unwrap(); let with_funcs = schema.with_funcs.unwrap(); - insta::assert_snapshot!(debug_print_tokenizable(with_funcs.declaration)); - insta::assert_snapshot!(debug_print_tokenizable(with_funcs.definitions)); + local_insta_assert_snapshot!(debug_print_tokenizable(with_funcs.declaration.clone())); + local_insta_assert_snapshot!(debug_print_tokenizable(with_funcs.definitions)); } // both `declaration` and `definitions` have to be specified @@ -574,18 +620,14 @@ mod tests { Ok(..) => unreachable!("expecting error here"), Err(err) => err, }; - insta::assert_debug_snapshot!(err); + local_insta_assert_debug_snapshot!(err); } #[test] - fn test_root_bounds_and_params_combined() { + fn test_root_error() { let item_struct: ItemStruct = syn::parse2(quote! { struct A { - #[borsh( - serialize_with = "third_party_impl::serialize_third_party", - bound(deserialize = "K: Hash"), - schema(params = "T => ::Associated, V => Vec") - )] + #[borsh(boons)] x: u64, y: String, } @@ -593,15 +635,11 @@ mod tests { .unwrap(); let first_field = &item_struct.fields.into_iter().collect::>()[0]; - - let attrs = Attributes::parse(&first_field.attrs, false).unwrap(); - let bounds = attrs.bounds.unwrap(); - assert!(bounds.serialize.is_none()); - insta::assert_snapshot!(debug_print_vec_of_tokenizable(bounds.deserialize)); - let schema = attrs.schema.unwrap(); - insta::assert_snapshot!(debug_print_vec_of_tokenizable(schema.params)); - insta::assert_snapshot!(debug_print_tokenizable(attrs.serialize_with)); - assert!(attrs.deserialize_with.is_none()); + let err = match Attributes::parse(&first_field.attrs, false) { + Ok(..) => unreachable!("expecting error here"), + Err(err) => err, + }; + local_insta_assert_debug_snapshot!(err); } #[test] @@ -623,6 +661,6 @@ mod tests { Ok(..) => unreachable!("expecting error here"), Err(err) => err, }; - insta::assert_debug_snapshot!(err); + local_insta_assert_debug_snapshot!(err); } } diff --git a/borsh-derive-internal/src/attribute_helpers/field/schema.rs b/borsh-derive/src/internals/attributes/field/schema.rs similarity index 91% rename from borsh-derive-internal/src/attribute_helpers/field/schema.rs rename to borsh-derive/src/internals/attributes/field/schema.rs index d00620269..01353bf18 100644 --- a/borsh-derive-internal/src/attribute_helpers/field/schema.rs +++ b/borsh-derive/src/internals/attributes/field/schema.rs @@ -1,8 +1,9 @@ use std::collections::BTreeMap; -use crate::attribute_helpers::{ +use crate::internals::attributes::{ parsing::{meta_get_by_symbol_keys, parse_lit_into_vec}, - Symbol, DECLARATION, DEFINITIONS, PARAMS, WITH_FUNCS, + schema_keys::{DECLARATION, DEFINITIONS, PARAMS, WITH_FUNCS}, + Symbol, }; use once_cell::sync::Lazy; use syn::{meta::ParseNestedMeta, Ident, Token, Type}; @@ -11,14 +12,14 @@ use self::with_funcs::{WithFuncs, WITH_FUNCS_FIELD_PARSE_MAP}; pub mod with_funcs; -pub(crate) enum Variants { +pub enum Variants { Params(Vec), WithFuncs(WithFuncs), } type ParseFn = dyn Fn(Symbol, Symbol, &ParseNestedMeta) -> syn::Result + Send + Sync; -pub(crate) static SCHEMA_FIELD_PARSE_MAP: Lazy>> = Lazy::new(|| { +pub static SCHEMA_FIELD_PARSE_MAP: Lazy>> = Lazy::new(|| { let mut m = BTreeMap::new(); // assigning closure `let f = |args| {...};` and boxing closure `let f: Box = Box::new(f);` // on 2 separate lines doesn't work @@ -59,7 +60,7 @@ pub struct ParameterOverride { } #[allow(unused)] -#[derive(Default)] +#[derive(Default, Clone)] pub(crate) struct Attributes { pub params: Option>, pub with_funcs: Option, diff --git a/borsh-schema-derive-internal/src/attribute_helpers/field/schema/with_funcs.rs b/borsh-derive/src/internals/attributes/field/schema/with_funcs.rs similarity index 53% rename from borsh-schema-derive-internal/src/attribute_helpers/field/schema/with_funcs.rs rename to borsh-derive/src/internals/attributes/field/schema/with_funcs.rs index 600cd0585..a30b9a85a 100644 --- a/borsh-schema-derive-internal/src/attribute_helpers/field/schema/with_funcs.rs +++ b/borsh-derive/src/internals/attributes/field/schema/with_funcs.rs @@ -3,36 +3,38 @@ use std::collections::BTreeMap; use once_cell::sync::Lazy; use syn::meta::ParseNestedMeta; -use crate::attribute_helpers::{parsing::parse_lit_into, Symbol, DECLARATION, DEFINITIONS}; +use crate::internals::attributes::{ + parsing::parse_lit_into, + schema_keys::{DECLARATION, DEFINITIONS}, + Symbol, +}; -pub(crate) enum Variants { +pub enum Variants { Declaration(syn::ExprPath), Definitions(syn::ExprPath), } type ParseFn = dyn Fn(Symbol, Symbol, &ParseNestedMeta) -> syn::Result + Send + Sync; -pub(crate) static WITH_FUNCS_FIELD_PARSE_MAP: Lazy>> = - Lazy::new(|| { - let mut m = BTreeMap::new(); - // assigning closure `let f = |args| {...};` and boxing closure `let f: Box = Box::new(f);` - // on 2 separate lines doesn't work - let f_declaration: Box = Box::new(|attr_name, meta_item_name, meta| { - parse_lit_into::(attr_name, meta_item_name, meta) - .map(Variants::Declaration) - }); - - let f_definitions: Box = Box::new(|attr_name, meta_item_name, meta| { - parse_lit_into::(attr_name, meta_item_name, meta) - .map(Variants::Definitions) - }); +pub static WITH_FUNCS_FIELD_PARSE_MAP: Lazy>> = Lazy::new(|| { + let mut m = BTreeMap::new(); + // assigning closure `let f = |args| {...};` and boxing closure `let f: Box = Box::new(f);` + // on 2 separate lines doesn't work + let f_declaration: Box = Box::new(|attr_name, meta_item_name, meta| { + parse_lit_into::(attr_name, meta_item_name, meta).map(Variants::Declaration) + }); - m.insert(DECLARATION, f_declaration); - m.insert(DEFINITIONS, f_definitions); - m + let f_definitions: Box = Box::new(|attr_name, meta_item_name, meta| { + parse_lit_into::(attr_name, meta_item_name, meta).map(Variants::Definitions) }); -pub(crate) struct WithFuncs { + m.insert(DECLARATION, f_declaration); + m.insert(DEFINITIONS, f_definitions); + m +}); + +#[derive(Clone)] +pub struct WithFuncs { pub declaration: Option, pub definitions: Option, } diff --git a/borsh-derive/src/internals/attributes/field/snapshots/bounds_parsing1-2.snap b/borsh-derive/src/internals/attributes/field/snapshots/bounds_parsing1-2.snap new file mode 100644 index 000000000..3c539b199 --- /dev/null +++ b/borsh-derive/src/internals/attributes/field/snapshots/bounds_parsing1-2.snap @@ -0,0 +1,7 @@ +--- +source: borsh-derive/src/internals/attributes/field/mod.rs +expression: debug_print_vec_of_tokenizable(attrs.deserialize) +--- +K : Hash + Ord +V : Eq + Ord + diff --git a/borsh-derive/src/internals/attributes/field/snapshots/bounds_parsing1.snap b/borsh-derive/src/internals/attributes/field/snapshots/bounds_parsing1.snap new file mode 100644 index 000000000..19c757409 --- /dev/null +++ b/borsh-derive/src/internals/attributes/field/snapshots/bounds_parsing1.snap @@ -0,0 +1,7 @@ +--- +source: borsh-derive/src/internals/attributes/field/mod.rs +expression: debug_print_vec_of_tokenizable(attrs.serialize.clone()) +--- +K : Hash + Eq + Ord +V : Ord + diff --git a/borsh-derive/src/internals/attributes/field/snapshots/bounds_parsing2-2.snap b/borsh-derive/src/internals/attributes/field/snapshots/bounds_parsing2-2.snap new file mode 100644 index 000000000..0ece71242 --- /dev/null +++ b/borsh-derive/src/internals/attributes/field/snapshots/bounds_parsing2-2.snap @@ -0,0 +1,7 @@ +--- +source: borsh-derive/src/internals/attributes/field/mod.rs +expression: debug_print_vec_of_tokenizable(attrs.deserialize) +--- +K : Hash + Eq + borsh :: de :: BorshDeserialize +V : borsh :: de :: BorshDeserialize + diff --git a/borsh-derive/src/internals/attributes/field/snapshots/bounds_parsing2.snap b/borsh-derive/src/internals/attributes/field/snapshots/bounds_parsing2.snap new file mode 100644 index 000000000..01f782969 --- /dev/null +++ b/borsh-derive/src/internals/attributes/field/snapshots/bounds_parsing2.snap @@ -0,0 +1,7 @@ +--- +source: borsh-derive/src/internals/attributes/field/mod.rs +expression: debug_print_vec_of_tokenizable(attrs.serialize.clone()) +--- +K : Hash + Eq + borsh :: ser :: BorshSerialize +V : borsh :: ser :: BorshSerialize + diff --git a/borsh-derive/src/internals/attributes/field/snapshots/bounds_parsing3.snap b/borsh-derive/src/internals/attributes/field/snapshots/bounds_parsing3.snap new file mode 100644 index 000000000..0ece71242 --- /dev/null +++ b/borsh-derive/src/internals/attributes/field/snapshots/bounds_parsing3.snap @@ -0,0 +1,7 @@ +--- +source: borsh-derive/src/internals/attributes/field/mod.rs +expression: debug_print_vec_of_tokenizable(attrs.deserialize) +--- +K : Hash + Eq + borsh :: de :: BorshDeserialize +V : borsh :: de :: BorshDeserialize + diff --git a/borsh-derive/src/internals/attributes/field/snapshots/bounds_parsing4.snap b/borsh-derive/src/internals/attributes/field/snapshots/bounds_parsing4.snap new file mode 100644 index 000000000..8a9b05f30 --- /dev/null +++ b/borsh-derive/src/internals/attributes/field/snapshots/bounds_parsing4.snap @@ -0,0 +1,6 @@ +--- +source: borsh-derive/src/internals/attributes/field/mod.rs +expression: debug_print_vec_of_tokenizable(attrs.deserialize) +--- +K : Hash + diff --git a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__bounds_parsing_error.snap b/borsh-derive/src/internals/attributes/field/snapshots/bounds_parsing_error.snap similarity index 66% rename from borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__bounds_parsing_error.snap rename to borsh-derive/src/internals/attributes/field/snapshots/bounds_parsing_error.snap index 39f31918a..db0a6e9a8 100644 --- a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__bounds_parsing_error.snap +++ b/borsh-derive/src/internals/attributes/field/snapshots/bounds_parsing_error.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/attribute_helpers/field.rs +source: borsh-derive/src/internals/attributes/field/mod.rs expression: err --- Error( diff --git a/borsh-derive/src/internals/attributes/field/snapshots/bounds_parsing_error2.snap b/borsh-derive/src/internals/attributes/field/snapshots/bounds_parsing_error2.snap new file mode 100644 index 000000000..fc006afe2 --- /dev/null +++ b/borsh-derive/src/internals/attributes/field/snapshots/bounds_parsing_error2.snap @@ -0,0 +1,7 @@ +--- +source: borsh-derive/src/internals/attributes/field/mod.rs +expression: err +--- +Error( + "expected `:`", +) diff --git a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__bounds_parsing_error3.snap b/borsh-derive/src/internals/attributes/field/snapshots/bounds_parsing_error3.snap similarity index 64% rename from borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__bounds_parsing_error3.snap rename to borsh-derive/src/internals/attributes/field/snapshots/bounds_parsing_error3.snap index 54518c743..9c23f5698 100644 --- a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__bounds_parsing_error3.snap +++ b/borsh-derive/src/internals/attributes/field/snapshots/bounds_parsing_error3.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/attribute_helpers/field.rs +source: borsh-derive/src/internals/attributes/field/mod.rs expression: err --- Error( diff --git a/borsh-derive/src/internals/attributes/field/snapshots/root_bounds_and_params_combined-2.snap b/borsh-derive/src/internals/attributes/field/snapshots/root_bounds_and_params_combined-2.snap new file mode 100644 index 000000000..c805b5f3f --- /dev/null +++ b/borsh-derive/src/internals/attributes/field/snapshots/root_bounds_and_params_combined-2.snap @@ -0,0 +1,7 @@ +--- +source: borsh-derive/src/internals/attributes/field/mod.rs +expression: debug_print_vec_of_tokenizable(schema.params.clone()) +--- +T => < T as TraitName > :: Associated +V => Vec < V > + diff --git a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__ser_de_with_parsing1.snap b/borsh-derive/src/internals/attributes/field/snapshots/root_bounds_and_params_combined-3.snap similarity index 64% rename from borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__ser_de_with_parsing1.snap rename to borsh-derive/src/internals/attributes/field/snapshots/root_bounds_and_params_combined-3.snap index 0b2b40540..4a6ed4cf4 100644 --- a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__ser_de_with_parsing1.snap +++ b/borsh-derive/src/internals/attributes/field/snapshots/root_bounds_and_params_combined-3.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/attribute_helpers/field.rs +source: borsh-derive/src/internals/attributes/field/mod.rs expression: debug_print_tokenizable(attrs.serialize_with) --- third_party_impl :: serialize_third_party diff --git a/borsh-derive/src/internals/attributes/field/snapshots/root_bounds_and_params_combined.snap b/borsh-derive/src/internals/attributes/field/snapshots/root_bounds_and_params_combined.snap new file mode 100644 index 000000000..5e5017be8 --- /dev/null +++ b/borsh-derive/src/internals/attributes/field/snapshots/root_bounds_and_params_combined.snap @@ -0,0 +1,6 @@ +--- +source: borsh-derive/src/internals/attributes/field/mod.rs +expression: debug_print_vec_of_tokenizable(bounds.deserialize) +--- +K : Hash + diff --git a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__root_error.snap b/borsh-derive/src/internals/attributes/field/snapshots/root_bounds_and_wrong_key_combined.snap similarity index 71% rename from borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__root_error.snap rename to borsh-derive/src/internals/attributes/field/snapshots/root_bounds_and_wrong_key_combined.snap index 3ece0af6e..7442e77c4 100644 --- a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__root_error.snap +++ b/borsh-derive/src/internals/attributes/field/snapshots/root_bounds_and_wrong_key_combined.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/attribute_helpers/field.rs +source: borsh-derive/src/internals/attributes/field/mod.rs expression: err --- Error( diff --git a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__root_bounds_and_wrong_key_combined.snap b/borsh-derive/src/internals/attributes/field/snapshots/root_error.snap similarity index 71% rename from borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__root_bounds_and_wrong_key_combined.snap rename to borsh-derive/src/internals/attributes/field/snapshots/root_error.snap index 3ece0af6e..7442e77c4 100644 --- a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__root_bounds_and_wrong_key_combined.snap +++ b/borsh-derive/src/internals/attributes/field/snapshots/root_error.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/attribute_helpers/field.rs +source: borsh-derive/src/internals/attributes/field/mod.rs expression: err --- Error( diff --git a/borsh-derive/src/internals/attributes/field/snapshots/schema_params_parsing1.snap b/borsh-derive/src/internals/attributes/field/snapshots/schema_params_parsing1.snap new file mode 100644 index 000000000..a5a116002 --- /dev/null +++ b/borsh-derive/src/internals/attributes/field/snapshots/schema_params_parsing1.snap @@ -0,0 +1,6 @@ +--- +source: borsh-derive/src/internals/attributes/field/mod.rs +expression: debug_print_vec_of_tokenizable(schema_attrs.unwrap().params) +--- +T => < T as TraitName > :: Associated + diff --git a/borsh-derive/src/internals/attributes/field/snapshots/schema_params_parsing2.snap b/borsh-derive/src/internals/attributes/field/snapshots/schema_params_parsing2.snap new file mode 100644 index 000000000..9627133e9 --- /dev/null +++ b/borsh-derive/src/internals/attributes/field/snapshots/schema_params_parsing2.snap @@ -0,0 +1,7 @@ +--- +source: borsh-derive/src/internals/attributes/field/mod.rs +expression: debug_print_vec_of_tokenizable(schema_attrs.unwrap().params) +--- +T => < T as TraitName > :: Associated +V => Vec < V > + diff --git a/borsh-derive/src/internals/attributes/field/snapshots/schema_params_parsing_error.snap b/borsh-derive/src/internals/attributes/field/snapshots/schema_params_parsing_error.snap new file mode 100644 index 000000000..492f3127b --- /dev/null +++ b/borsh-derive/src/internals/attributes/field/snapshots/schema_params_parsing_error.snap @@ -0,0 +1,7 @@ +--- +source: borsh-derive/src/internals/attributes/field/mod.rs +expression: err +--- +Error( + "expected `>`", +) diff --git a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__schema_params_parsing_error2.snap b/borsh-derive/src/internals/attributes/field/snapshots/schema_params_parsing_error2.snap similarity index 65% rename from borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__schema_params_parsing_error2.snap rename to borsh-derive/src/internals/attributes/field/snapshots/schema_params_parsing_error2.snap index cf4a88fd4..8eed50d3c 100644 --- a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__schema_params_parsing_error2.snap +++ b/borsh-derive/src/internals/attributes/field/snapshots/schema_params_parsing_error2.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/attribute_helpers/field.rs +source: borsh-derive/src/internals/attributes/field/mod.rs expression: err --- Error( diff --git a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__schema_with_funcs_parsing-2.snap b/borsh-derive/src/internals/attributes/field/snapshots/schema_with_funcs_parsing-2.snap similarity index 68% rename from borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__schema_with_funcs_parsing-2.snap rename to borsh-derive/src/internals/attributes/field/snapshots/schema_with_funcs_parsing-2.snap index e008038ad..49d8fb91f 100644 --- a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__schema_with_funcs_parsing-2.snap +++ b/borsh-derive/src/internals/attributes/field/snapshots/schema_with_funcs_parsing-2.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/attribute_helpers/field.rs +source: borsh-derive/src/internals/attributes/field/mod.rs expression: debug_print_tokenizable(with_funcs.definitions) --- third_party_impl :: add_definitions_recursively :: < K , V > diff --git a/borsh-derive/src/internals/attributes/field/snapshots/schema_with_funcs_parsing.snap b/borsh-derive/src/internals/attributes/field/snapshots/schema_with_funcs_parsing.snap new file mode 100644 index 000000000..836792a76 --- /dev/null +++ b/borsh-derive/src/internals/attributes/field/snapshots/schema_with_funcs_parsing.snap @@ -0,0 +1,6 @@ +--- +source: borsh-derive/src/internals/attributes/field/mod.rs +expression: debug_print_tokenizable(with_funcs.declaration.clone()) +--- +third_party_impl :: declaration :: < K , V > + diff --git a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__schema_with_funcs_parsing_error.snap b/borsh-derive/src/internals/attributes/field/snapshots/schema_with_funcs_parsing_error.snap similarity index 67% rename from borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__schema_with_funcs_parsing_error.snap rename to borsh-derive/src/internals/attributes/field/snapshots/schema_with_funcs_parsing_error.snap index 888eed542..82f887b73 100644 --- a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__schema_with_funcs_parsing_error.snap +++ b/borsh-derive/src/internals/attributes/field/snapshots/schema_with_funcs_parsing_error.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/attribute_helpers/field.rs +source: borsh-derive/src/internals/attributes/field/mod.rs expression: err --- Error( diff --git a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__ser_de_with_parsing1-2.snap b/borsh-derive/src/internals/attributes/field/snapshots/ser_de_with_parsing1-2.snap similarity index 64% rename from borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__ser_de_with_parsing1-2.snap rename to borsh-derive/src/internals/attributes/field/snapshots/ser_de_with_parsing1-2.snap index f3e6cec11..85a4d0b8d 100644 --- a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__field__tests__ser_de_with_parsing1-2.snap +++ b/borsh-derive/src/internals/attributes/field/snapshots/ser_de_with_parsing1-2.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/attribute_helpers/field.rs +source: borsh-derive/src/internals/attributes/field/mod.rs expression: debug_print_tokenizable(attrs.deserialize_with) --- third_party_impl :: deserialize_third_party diff --git a/borsh-derive/src/internals/attributes/field/snapshots/ser_de_with_parsing1.snap b/borsh-derive/src/internals/attributes/field/snapshots/ser_de_with_parsing1.snap new file mode 100644 index 000000000..b03de7f03 --- /dev/null +++ b/borsh-derive/src/internals/attributes/field/snapshots/ser_de_with_parsing1.snap @@ -0,0 +1,6 @@ +--- +source: borsh-derive/src/internals/attributes/field/mod.rs +expression: debug_print_tokenizable(attrs.serialize_with.as_ref()) +--- +third_party_impl :: serialize_third_party + diff --git a/borsh-derive-internal/src/attribute_helpers/mod.rs b/borsh-derive/src/internals/attributes/item/mod.rs similarity index 66% rename from borsh-derive-internal/src/attribute_helpers/mod.rs rename to borsh-derive/src/internals/attributes/item/mod.rs index 3735e3f58..1538bf048 100644 --- a/borsh-derive-internal/src/attribute_helpers/mod.rs +++ b/borsh-derive/src/internals/attributes/item/mod.rs @@ -1,65 +1,8 @@ +use crate::internals::attributes::{BORSH, INIT, SKIP, USE_DISCRIMINANT}; use proc_macro2::TokenStream; use quote::ToTokens; use syn::{spanned::Spanned, Attribute, DeriveInput, Expr, ItemEnum, Path}; -pub mod field; -pub mod parsing; - -/// first field is attr name -/// second field is its expected value format representation for error printing -#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord)] -pub struct Symbol(pub &'static str, pub &'static str); - -/// borsh - top level prefix in nested meta attribute -pub const BORSH: Symbol = Symbol("borsh", "borsh(...)"); -/// bound - sub-borsh nested meta, field-level only, `BorshSerialize` and `BorshDeserialize` contexts -pub const BOUND: Symbol = Symbol("bound", "bound(...)"); -// use_discriminant - sub-borsh nested meta, item-level only, enums only, `BorshSerialize` and `BorshDeserialize` contexts -pub const USE_DISCRIMINANT: &str = "use_discriminant"; -/// serialize - sub-bound nested meta attribute -pub const SERIALIZE: Symbol = Symbol("serialize", "serialize = ..."); -/// deserialize - sub-bound nested meta attribute -pub const DESERIALIZE: Symbol = Symbol("deserialize", "deserialize = ..."); -/// borsh_skip - field-level only attribute, `BorshSerialize`, `BorshDeserialize`, `BorshSchema` contexts -pub const SKIP: Symbol = Symbol("borsh_skip", "borsh_skip"); -/// borsh_init - item-level only attribute `BorshDeserialize` context -pub const INIT: Symbol = Symbol("borsh_init", "borsh_init(...)"); -/// schema - sub-borsh nested meta, `BorshSchema` context -pub const SCHEMA: Symbol = Symbol("schema", "schema(...)"); -/// params - sub-schema nested meta, field-level only attribute -pub const PARAMS: Symbol = Symbol("params", "params = ..."); -/// serialize_with - sub-borsh nested meta, field-level only, `BorshSerialize` context -pub const SERIALIZE_WITH: Symbol = Symbol("serialize_with", "serialize_with = ..."); -/// deserialize_with - sub-borsh nested meta, field-level only, `BorshDeserialize` context -pub const DESERIALIZE_WITH: Symbol = Symbol("deserialize_with", "deserialize_with = ..."); -/// with_funcs - sub-schema nested meta, field-level only attribute -pub const WITH_FUNCS: Symbol = Symbol("with_funcs", "with_funcs(...)"); -/// declaration - sub-with_funcs nested meta, field-level only attribute -pub const DECLARATION: Symbol = Symbol("declaration", "declaration = ..."); -/// definitions - sub-with_funcs nested meta, field-level only attribute -pub const DEFINITIONS: Symbol = Symbol("definitions", "definitions = ..."); - -#[derive(Clone, Copy)] -pub(crate) enum BoundType { - Serialize, - Deserialize, -} -impl PartialEq for Path { - fn eq(&self, word: &Symbol) -> bool { - self.is_ident(word.0) - } -} - -impl<'a> PartialEq for &'a Path { - fn eq(&self, word: &Symbol) -> bool { - self.is_ident(word.0) - } -} - -pub(crate) fn contains_skip(attrs: &[Attribute]) -> bool { - attrs.iter().any(|attr| attr.path() == SKIP) -} - pub fn check_item_attributes(derive_input: &DeriveInput) -> Result<(), TokenStream> { for attr in &derive_input.attrs { if attr.path().is_ident(SKIP.0) { @@ -95,7 +38,7 @@ pub fn check_item_attributes(derive_input: &DeriveInput) -> Result<(), TokenStre Ok(()) } -pub(crate) fn contains_use_discriminant(input: &ItemEnum) -> Result { +pub fn contains_use_discriminant(input: &ItemEnum) -> Result { if input.variants.len() > 256 { return Err(syn::Error::new( input.span(), @@ -159,7 +102,11 @@ pub(crate) fn contains_initialize_with(attrs: &[Attribute]) -> Option { #[cfg(test)] mod tests { + use crate::internals::test_helpers::{ + local_insta_assert_debug_snapshot, local_insta_assert_snapshot, + }; use quote::{quote, ToTokens}; + use syn::ItemEnum; use super::*; #[test] @@ -208,7 +155,7 @@ mod tests { Ok(..) => unreachable!("expecting error here"), Err(err) => err, }; - insta::assert_debug_snapshot!(err); + local_insta_assert_debug_snapshot!(err); } #[test] fn test_check_use_discriminant_on_struct() { @@ -222,7 +169,7 @@ mod tests { }) .unwrap(); let actual = check_item_attributes(&item_enum); - insta::assert_snapshot!(actual.unwrap_err().to_token_stream().to_string()); + local_insta_assert_snapshot!(actual.unwrap_err().to_token_stream().to_string()); } #[test] fn test_check_use_borsh_skip_on_whole_struct() { @@ -236,7 +183,7 @@ mod tests { }) .unwrap(); let actual = check_item_attributes(&item_enum); - insta::assert_snapshot!(actual.unwrap_err().to_token_stream().to_string()); + local_insta_assert_snapshot!(actual.unwrap_err().to_token_stream().to_string()); } #[test] fn test_check_use_borsh_invalid_on_whole_struct() { @@ -250,6 +197,6 @@ mod tests { }) .unwrap(); let actual = check_item_attributes(&item_enum); - insta::assert_snapshot!(actual.unwrap_err().to_token_stream().to_string()); + local_insta_assert_snapshot!(actual.unwrap_err().to_token_stream().to_string()); } } diff --git a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__tests__check_use_borsh_invalid_on_whole_struct.snap b/borsh-derive/src/internals/attributes/item/snapshots/check_use_borsh_invalid_on_whole_struct.snap similarity index 73% rename from borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__tests__check_use_borsh_invalid_on_whole_struct.snap rename to borsh-derive/src/internals/attributes/item/snapshots/check_use_borsh_invalid_on_whole_struct.snap index fb0ccab19..8d747ec07 100644 --- a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__tests__check_use_borsh_invalid_on_whole_struct.snap +++ b/borsh-derive/src/internals/attributes/item/snapshots/check_use_borsh_invalid_on_whole_struct.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/attribute_helpers/mod.rs +source: borsh-derive/src/internals/attributes/item/mod.rs expression: actual.unwrap_err().to_token_stream().to_string() --- :: core :: compile_error ! { "`use_discriminant` is the only supported attribute for `borsh`" } diff --git a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__tests__check_use_borsh_skip_on_whole_struct.snap b/borsh-derive/src/internals/attributes/item/snapshots/check_use_borsh_skip_on_whole_struct.snap similarity index 72% rename from borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__tests__check_use_borsh_skip_on_whole_struct.snap rename to borsh-derive/src/internals/attributes/item/snapshots/check_use_borsh_skip_on_whole_struct.snap index 2a5c1d170..676578565 100644 --- a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__tests__check_use_borsh_skip_on_whole_struct.snap +++ b/borsh-derive/src/internals/attributes/item/snapshots/check_use_borsh_skip_on_whole_struct.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/attribute_helpers/mod.rs +source: borsh-derive/src/internals/attributes/item/mod.rs expression: actual.unwrap_err().to_token_stream().to_string() --- :: core :: compile_error ! { "`borsh_skip` is not allowed as derive input attribute" } diff --git a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__tests__check_use_discriminant_on_struct.snap b/borsh-derive/src/internals/attributes/item/snapshots/check_use_discriminant_on_struct.snap similarity index 72% rename from borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__tests__check_use_discriminant_on_struct.snap rename to borsh-derive/src/internals/attributes/item/snapshots/check_use_discriminant_on_struct.snap index d149e0649..cfe5e0d30 100644 --- a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__tests__check_use_discriminant_on_struct.snap +++ b/borsh-derive/src/internals/attributes/item/snapshots/check_use_discriminant_on_struct.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/attribute_helpers/mod.rs +source: borsh-derive/src/internals/attributes/item/mod.rs expression: actual.unwrap_err().to_token_stream().to_string() --- :: core :: compile_error ! { "borsh(use_discriminant=) does not support structs" } diff --git a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__tests__check_use_discriminant_wrong_value.snap b/borsh-derive/src/internals/attributes/item/snapshots/check_use_discriminant_wrong_value.snap similarity index 60% rename from borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__tests__check_use_discriminant_wrong_value.snap rename to borsh-derive/src/internals/attributes/item/snapshots/check_use_discriminant_wrong_value.snap index 62626a318..81b53a54b 100644 --- a/borsh-derive-internal/src/attribute_helpers/snapshots/borsh_derive_internal__attribute_helpers__tests__check_use_discriminant_wrong_value.snap +++ b/borsh-derive/src/internals/attributes/item/snapshots/check_use_discriminant_wrong_value.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/attribute_helpers/mod.rs +source: borsh-derive/src/internals/attributes/item/mod.rs expression: err --- Error( diff --git a/borsh-derive/src/internals/attributes/mod.rs b/borsh-derive/src/internals/attributes/mod.rs new file mode 100644 index 000000000..24f0858ad --- /dev/null +++ b/borsh-derive/src/internals/attributes/mod.rs @@ -0,0 +1,63 @@ +use syn::Path; + +pub mod field; +pub mod item; +pub mod parsing; + +/// first field is attr name +/// second field is its expected value format representation for error printing +#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord)] +pub struct Symbol(pub &'static str, pub &'static str); + +/// borsh - top level prefix in nested meta attribute +pub const BORSH: Symbol = Symbol("borsh", "borsh(...)"); +/// bound - sub-borsh nested meta, field-level only, `BorshSerialize` and `BorshDeserialize` contexts +pub const BOUND: Symbol = Symbol("bound", "bound(...)"); +// use_discriminant - sub-borsh nested meta, item-level only, enums only, `BorshSerialize` and `BorshDeserialize` contexts +pub const USE_DISCRIMINANT: &str = "use_discriminant"; +/// serialize - sub-bound nested meta attribute +pub const SERIALIZE: Symbol = Symbol("serialize", "serialize = ..."); +/// deserialize - sub-bound nested meta attribute +pub const DESERIALIZE: Symbol = Symbol("deserialize", "deserialize = ..."); +/// borsh_skip - field-level only attribute, `BorshSerialize`, `BorshDeserialize`, `BorshSchema` contexts +pub const SKIP: Symbol = Symbol("borsh_skip", "borsh_skip"); +/// borsh_init - item-level only attribute `BorshDeserialize` context +pub const INIT: Symbol = Symbol("borsh_init", "borsh_init(...)"); +/// serialize_with - sub-borsh nested meta, field-level only, `BorshSerialize` context +pub const SERIALIZE_WITH: Symbol = Symbol("serialize_with", "serialize_with = ..."); +/// deserialize_with - sub-borsh nested meta, field-level only, `BorshDeserialize` context +pub const DESERIALIZE_WITH: Symbol = Symbol("deserialize_with", "deserialize_with = ..."); + +#[cfg(feature = "schema")] +pub mod schema_keys { + use super::Symbol; + + /// schema - sub-borsh nested meta, `BorshSchema` context + pub const SCHEMA: Symbol = Symbol("schema", "schema(...)"); + /// params - sub-schema nested meta, field-level only attribute + pub const PARAMS: Symbol = Symbol("params", "params = ..."); + /// serialize_with - sub-borsh nested meta, field-level only, `BorshSerialize` context + /// with_funcs - sub-schema nested meta, field-level only attribute + pub const WITH_FUNCS: Symbol = Symbol("with_funcs", "with_funcs(...)"); + /// declaration - sub-with_funcs nested meta, field-level only attribute + pub const DECLARATION: Symbol = Symbol("declaration", "declaration = ..."); + /// definitions - sub-with_funcs nested meta, field-level only attribute + pub const DEFINITIONS: Symbol = Symbol("definitions", "definitions = ..."); +} + +#[derive(Clone, Copy)] +pub enum BoundType { + Serialize, + Deserialize, +} +impl PartialEq for Path { + fn eq(&self, word: &Symbol) -> bool { + self.is_ident(word.0) + } +} + +impl<'a> PartialEq for &'a Path { + fn eq(&self, word: &Symbol) -> bool { + self.is_ident(word.0) + } +} diff --git a/borsh-derive-internal/src/attribute_helpers/parsing.rs b/borsh-derive/src/internals/attributes/parsing.rs similarity index 100% rename from borsh-derive-internal/src/attribute_helpers/parsing.rs rename to borsh-derive/src/internals/attributes/parsing.rs diff --git a/borsh-derive-internal/src/enum_de.rs b/borsh-derive/src/internals/deserialize/enums/mod.rs similarity index 79% rename from borsh-derive-internal/src/enum_de.rs rename to borsh-derive/src/internals/deserialize/enums/mod.rs index f644ac084..0c5a285a1 100644 --- a/borsh-derive-internal/src/enum_de.rs +++ b/borsh-derive/src/internals/deserialize/enums/mod.rs @@ -2,19 +2,15 @@ use proc_macro2::TokenStream as TokenStream2; use quote::quote; use syn::{Fields, Ident, ItemEnum, Path, WhereClause}; -use crate::{ - attribute_helpers::{ - contains_initialize_with, contains_skip, contains_use_discriminant, field, BoundType, - }, - enum_discriminant_map::discriminant_map, - generics::{compute_predicates, without_defaults, FindTyParams}, - struct_de::field_deserialization_output, +use crate::internals::{ + attributes::{field, item, BoundType}, + deserialize, enum_discriminant, generics, }; use std::convert::TryFrom; -pub fn enum_de(input: &ItemEnum, cratename: Ident) -> syn::Result { +pub fn process(input: &ItemEnum, cratename: Ident) -> syn::Result { let name = &input.ident; - let generics = without_defaults(&input.generics); + let generics = generics::without_defaults(&input.generics); let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); let mut where_clause = where_clause.map_or_else( || WhereClause { @@ -25,15 +21,15 @@ pub fn enum_de(input: &ItemEnum, cratename: Ident) -> syn::Result ); let mut override_predicates = vec![]; - let mut deserialize_params_visitor = FindTyParams::new(&generics); - let mut default_params_visitor = FindTyParams::new(&generics); + let mut deserialize_params_visitor = generics::FindTyParams::new(&generics); + let mut default_params_visitor = generics::FindTyParams::new(&generics); - let init_method = contains_initialize_with(&input.attrs); + let init_method = item::contains_initialize_with(&input.attrs); - let use_discriminant = contains_use_discriminant(input)?; + let use_discriminant = item::contains_use_discriminant(input)?; let mut variant_arms = TokenStream2::new(); - let discriminants = discriminant_map(&input.variants); + let discriminants = enum_discriminant::map(&input.variants); for (variant_idx, variant) in input.variants.iter().enumerate() { let variant_idx = u8::try_from(variant_idx).map_err(|err| { @@ -48,7 +44,7 @@ pub fn enum_de(input: &ItemEnum, cratename: Ident) -> syn::Result match &variant.fields { Fields::Named(fields) => { for field in &fields.named { - let skipped = contains_skip(&field.attrs); + let skipped = field::contains_skip(&field.attrs); let parsed = field::Attributes::parse(&field.attrs, skipped)?; override_predicates.extend(parsed.collect_bounds(BoundType::Deserialize)); let needs_bounds_derive = parsed.needs_bounds_derive(BoundType::Deserialize); @@ -65,7 +61,7 @@ pub fn enum_de(input: &ItemEnum, cratename: Ident) -> syn::Result deserialize_params_visitor.visit_field(field); } - variant_header.extend(field_deserialization_output( + variant_header.extend(deserialize::field_output( Some(field_name), &cratename, parsed.deserialize_with, @@ -76,7 +72,7 @@ pub fn enum_de(input: &ItemEnum, cratename: Ident) -> syn::Result } Fields::Unnamed(fields) => { for field in fields.unnamed.iter() { - let skipped = contains_skip(&field.attrs); + let skipped = field::contains_skip(&field.attrs); let parsed = field::Attributes::parse(&field.attrs, skipped)?; override_predicates.extend(parsed.collect_bounds(BoundType::Deserialize)); @@ -90,7 +86,7 @@ pub fn enum_de(input: &ItemEnum, cratename: Ident) -> syn::Result if needs_bounds_derive { deserialize_params_visitor.visit_field(field); } - variant_header.extend(field_deserialization_output( + variant_header.extend(deserialize::field_output( None, &cratename, parsed.deserialize_with, @@ -121,11 +117,11 @@ pub fn enum_de(input: &ItemEnum, cratename: Ident) -> syn::Result let de_trait_path: Path = syn::parse2(quote! { #cratename::de::BorshDeserialize }).unwrap(); let default_trait_path: Path = syn::parse2(quote! { core::default::Default }).unwrap(); - let de_predicates = compute_predicates( + let de_predicates = generics::compute_predicates( deserialize_params_visitor.process_for_bounds(), &de_trait_path, ); - let default_predicates = compute_predicates( + let default_predicates = generics::compute_predicates( default_params_visitor.process_for_bounds(), &default_trait_path, ); @@ -161,7 +157,7 @@ pub fn enum_de(input: &ItemEnum, cratename: Ident) -> syn::Result #[cfg(test)] mod tests { - use crate::test_helpers::pretty_print_syn_str; + use crate::internals::test_helpers::{local_insta_assert_snapshot, pretty_print_syn_str}; use super::*; use proc_macro2::Span; @@ -181,9 +177,9 @@ mod tests { } }) .unwrap(); - let actual = enum_de(&item_enum, Ident::new("borsh", Span::call_site())).unwrap(); + let actual = process(&item_enum, Ident::new("borsh", Span::call_site())).unwrap(); - insta::assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); + local_insta_assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); } #[test] @@ -198,9 +194,9 @@ mod tests { } }) .unwrap(); - let actual = enum_de(&item_enum, Ident::new("borsh", Span::call_site())).unwrap(); + let actual = process(&item_enum, Ident::new("borsh", Span::call_site())).unwrap(); - insta::assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); + local_insta_assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); } #[test] @@ -216,8 +212,8 @@ mod tests { }) .unwrap(); - let actual = enum_de(&item_struct, Ident::new("borsh", Span::call_site())).unwrap(); - insta::assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); + let actual = process(&item_struct, Ident::new("borsh", Span::call_site())).unwrap(); + local_insta_assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); } #[test] @@ -233,8 +229,8 @@ mod tests { }) .unwrap(); - let actual = enum_de(&item_struct, Ident::new("borsh", Span::call_site())).unwrap(); - insta::assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); + let actual = process(&item_struct, Ident::new("borsh", Span::call_site())).unwrap(); + local_insta_assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); } #[test] @@ -250,9 +246,9 @@ mod tests { }) .unwrap(); - let actual = enum_de(&item_struct, Ident::new("borsh", Span::call_site())).unwrap(); + let actual = process(&item_struct, Ident::new("borsh", Span::call_site())).unwrap(); - insta::assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); + local_insta_assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); } #[test] fn generic_borsh_skip_struct_field() { @@ -268,9 +264,9 @@ mod tests { }) .unwrap(); - let actual = enum_de(&item_struct, Ident::new("borsh", Span::call_site())).unwrap(); + let actual = process(&item_struct, Ident::new("borsh", Span::call_site())).unwrap(); - insta::assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); + local_insta_assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); } #[test] @@ -286,9 +282,9 @@ mod tests { }) .unwrap(); - let actual = enum_de(&item_struct, Ident::new("borsh", Span::call_site())).unwrap(); + let actual = process(&item_struct, Ident::new("borsh", Span::call_site())).unwrap(); - insta::assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); + local_insta_assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); } #[test] @@ -308,9 +304,9 @@ mod tests { }) .unwrap(); - let actual = enum_de(&item_struct, Ident::new("borsh", Span::call_site())).unwrap(); + let actual = process(&item_struct, Ident::new("borsh", Span::call_site())).unwrap(); - insta::assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); + local_insta_assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); } #[test] @@ -327,9 +323,9 @@ mod tests { }) .unwrap(); - let actual = enum_de(&item_struct, Ident::new("borsh", Span::call_site())).unwrap(); + let actual = process(&item_struct, Ident::new("borsh", Span::call_site())).unwrap(); - insta::assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); + local_insta_assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); } #[test] @@ -346,9 +342,9 @@ mod tests { } }) .unwrap(); - let actual = enum_de(&item_enum, Ident::new("borsh", Span::call_site())).unwrap(); + let actual = process(&item_enum, Ident::new("borsh", Span::call_site())).unwrap(); - insta::assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); + local_insta_assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); } #[test] fn borsh_discriminant_true() { @@ -364,8 +360,8 @@ mod tests { } }) .unwrap(); - let actual = enum_de(&item_enum, Ident::new("borsh", Span::call_site())).unwrap(); + let actual = process(&item_enum, Ident::new("borsh", Span::call_site())).unwrap(); - insta::assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); + local_insta_assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); } } diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_de__tests__borsh_discriminant_false.snap b/borsh-derive/src/internals/deserialize/enums/snapshots/borsh_discriminant_false.snap similarity index 95% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_de__tests__borsh_discriminant_false.snap rename to borsh-derive/src/internals/deserialize/enums/snapshots/borsh_discriminant_false.snap index c5e95d7cc..947f64775 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_de__tests__borsh_discriminant_false.snap +++ b/borsh-derive/src/internals/deserialize/enums/snapshots/borsh_discriminant_false.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/enum_de.rs +source: borsh-derive/src/internals/deserialize/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::de::BorshDeserialize for X { diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_de__tests__borsh_discriminant_true.snap b/borsh-derive/src/internals/deserialize/enums/snapshots/borsh_discriminant_true.snap similarity index 95% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_de__tests__borsh_discriminant_true.snap rename to borsh-derive/src/internals/deserialize/enums/snapshots/borsh_discriminant_true.snap index d460c3e1b..47e0eb2d1 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_de__tests__borsh_discriminant_true.snap +++ b/borsh-derive/src/internals/deserialize/enums/snapshots/borsh_discriminant_true.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/enum_de.rs +source: borsh-derive/src/internals/deserialize/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::de::BorshDeserialize for X { diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_de__tests__borsh_skip_struct_variant_field.snap b/borsh-derive/src/internals/deserialize/enums/snapshots/borsh_skip_struct_variant_field.snap similarity index 96% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_de__tests__borsh_skip_struct_variant_field.snap rename to borsh-derive/src/internals/deserialize/enums/snapshots/borsh_skip_struct_variant_field.snap index 05e35ae19..e713d3b90 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_de__tests__borsh_skip_struct_variant_field.snap +++ b/borsh-derive/src/internals/deserialize/enums/snapshots/borsh_skip_struct_variant_field.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/enum_de.rs +source: borsh-derive/src/internals/deserialize/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::de::BorshDeserialize for AA { diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_de__tests__borsh_skip_tuple_variant_field.snap b/borsh-derive/src/internals/deserialize/enums/snapshots/borsh_skip_tuple_variant_field.snap similarity index 96% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_de__tests__borsh_skip_tuple_variant_field.snap rename to borsh-derive/src/internals/deserialize/enums/snapshots/borsh_skip_tuple_variant_field.snap index 77b3b0919..d4ee49688 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_de__tests__borsh_skip_tuple_variant_field.snap +++ b/borsh-derive/src/internals/deserialize/enums/snapshots/borsh_skip_tuple_variant_field.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/enum_de.rs +source: borsh-derive/src/internals/deserialize/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::de::BorshDeserialize for AAT { diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_de__tests__bound_generics.snap b/borsh-derive/src/internals/deserialize/enums/snapshots/bound_generics.snap similarity index 96% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_de__tests__bound_generics.snap rename to borsh-derive/src/internals/deserialize/enums/snapshots/bound_generics.snap index 60eb6ac23..40a04b83a 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_de__tests__bound_generics.snap +++ b/borsh-derive/src/internals/deserialize/enums/snapshots/bound_generics.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/enum_de.rs +source: borsh-derive/src/internals/deserialize/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::de::BorshDeserialize for A diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_de__tests__check_deserialize_with_attr.snap b/borsh-derive/src/internals/deserialize/enums/snapshots/check_deserialize_with_attr.snap similarity index 96% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_de__tests__check_deserialize_with_attr.snap rename to borsh-derive/src/internals/deserialize/enums/snapshots/check_deserialize_with_attr.snap index 2fdb14f75..452928cad 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_de__tests__check_deserialize_with_attr.snap +++ b/borsh-derive/src/internals/deserialize/enums/snapshots/check_deserialize_with_attr.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/enum_de.rs +source: borsh-derive/src/internals/deserialize/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::de::BorshDeserialize for C diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_de__tests__generic_borsh_skip_struct_field.snap b/borsh-derive/src/internals/deserialize/enums/snapshots/generic_borsh_skip_struct_field.snap similarity index 96% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_de__tests__generic_borsh_skip_struct_field.snap rename to borsh-derive/src/internals/deserialize/enums/snapshots/generic_borsh_skip_struct_field.snap index 2659939bd..963d6ac71 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_de__tests__generic_borsh_skip_struct_field.snap +++ b/borsh-derive/src/internals/deserialize/enums/snapshots/generic_borsh_skip_struct_field.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/enum_de.rs +source: borsh-derive/src/internals/deserialize/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::de::BorshDeserialize for A diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_de__tests__generic_borsh_skip_tuple_field.snap b/borsh-derive/src/internals/deserialize/enums/snapshots/generic_borsh_skip_tuple_field.snap similarity index 96% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_de__tests__generic_borsh_skip_tuple_field.snap rename to borsh-derive/src/internals/deserialize/enums/snapshots/generic_borsh_skip_tuple_field.snap index 7ab273dd5..53bd55600 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_de__tests__generic_borsh_skip_tuple_field.snap +++ b/borsh-derive/src/internals/deserialize/enums/snapshots/generic_borsh_skip_tuple_field.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/enum_de.rs +source: borsh-derive/src/internals/deserialize/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::de::BorshDeserialize for A diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_de__tests__generic_deserialize_bound.snap b/borsh-derive/src/internals/deserialize/enums/snapshots/generic_deserialize_bound.snap similarity index 96% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_de__tests__generic_deserialize_bound.snap rename to borsh-derive/src/internals/deserialize/enums/snapshots/generic_deserialize_bound.snap index b9ec60a4d..0aa0c8066 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_de__tests__generic_deserialize_bound.snap +++ b/borsh-derive/src/internals/deserialize/enums/snapshots/generic_deserialize_bound.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/enum_de.rs +source: borsh-derive/src/internals/deserialize/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::de::BorshDeserialize for A diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_de__tests__recursive_enum.snap b/borsh-derive/src/internals/deserialize/enums/snapshots/recursive_enum.snap similarity index 96% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_de__tests__recursive_enum.snap rename to borsh-derive/src/internals/deserialize/enums/snapshots/recursive_enum.snap index 54761fbdf..fa8c7380c 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_de__tests__recursive_enum.snap +++ b/borsh-derive/src/internals/deserialize/enums/snapshots/recursive_enum.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/enum_de.rs +source: borsh-derive/src/internals/deserialize/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::de::BorshDeserialize for A diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_de__tests__simple_generics.snap b/borsh-derive/src/internals/deserialize/enums/snapshots/simple_generics.snap similarity index 96% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_de__tests__simple_generics.snap rename to borsh-derive/src/internals/deserialize/enums/snapshots/simple_generics.snap index d61d0bff4..b9f06565d 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_de__tests__simple_generics.snap +++ b/borsh-derive/src/internals/deserialize/enums/snapshots/simple_generics.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/enum_de.rs +source: borsh-derive/src/internals/deserialize/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::de::BorshDeserialize for A diff --git a/borsh-derive/src/internals/deserialize/mod.rs b/borsh-derive/src/internals/deserialize/mod.rs new file mode 100644 index 000000000..5c12caf0a --- /dev/null +++ b/borsh-derive/src/internals/deserialize/mod.rs @@ -0,0 +1,28 @@ +use proc_macro2::TokenStream as TokenStream2; +use quote::quote; +use syn::{ExprPath, Ident}; + +pub mod enums; +pub mod structs; +pub mod unions; + +/// function which computes derive output [proc_macro2::TokenStream] +/// of code, which deserializes single field +fn field_output( + field_name: Option<&Ident>, + cratename: &Ident, + deserialize_with: Option, +) -> TokenStream2 { + let default_path: ExprPath = + syn::parse2(quote! { #cratename::BorshDeserialize::deserialize_reader }).unwrap(); + let path: ExprPath = deserialize_with.unwrap_or(default_path); + if let Some(field_name) = field_name { + quote! { + #field_name: #path(reader)?, + } + } else { + quote! { + #path(reader)?, + } + } +} diff --git a/borsh-derive-internal/src/struct_de.rs b/borsh-derive/src/internals/deserialize/structs/mod.rs similarity index 66% rename from borsh-derive-internal/src/struct_de.rs rename to borsh-derive/src/internals/deserialize/structs/mod.rs index f6e5cede3..f2cb7e564 100644 --- a/borsh-derive-internal/src/struct_de.rs +++ b/borsh-derive/src/internals/deserialize/structs/mod.rs @@ -1,36 +1,15 @@ use proc_macro2::TokenStream as TokenStream2; use quote::quote; -use syn::{ExprPath, Fields, Ident, ItemStruct, Path, WhereClause}; +use syn::{Fields, Ident, ItemStruct, Path, WhereClause}; -use crate::{ - attribute_helpers::{contains_initialize_with, contains_skip, field, BoundType}, - generics::{compute_predicates, without_defaults, FindTyParams}, +use crate::internals::{ + attributes::{field, item, BoundType}, + deserialize, generics, }; -/// function which computes derive output [proc_macro2::TokenStream] -/// of code, which deserializes single field -pub(crate) fn field_deserialization_output( - field_name: Option<&Ident>, - cratename: &Ident, - deserialize_with: Option, -) -> TokenStream2 { - let default_path: ExprPath = - syn::parse2(quote! { #cratename::BorshDeserialize::deserialize_reader }).unwrap(); - let path: ExprPath = deserialize_with.unwrap_or(default_path); - if let Some(field_name) = field_name { - quote! { - #field_name: #path(reader)?, - } - } else { - quote! { - #path(reader)?, - } - } -} - -pub fn struct_de(input: &ItemStruct, cratename: Ident) -> syn::Result { +pub fn process(input: &ItemStruct, cratename: Ident) -> syn::Result { let name = &input.ident; - let generics = without_defaults(&input.generics); + let generics = generics::without_defaults(&input.generics); let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); let mut where_clause = where_clause.map_or_else( || WhereClause { @@ -41,15 +20,15 @@ pub fn struct_de(input: &ItemStruct, cratename: Ident) -> syn::Result { let mut body = TokenStream2::new(); for field in &fields.named { - let skipped = contains_skip(&field.attrs); + let skipped = field::contains_skip(&field.attrs); let parsed = field::Attributes::parse(&field.attrs, skipped)?; override_predicates.extend(parsed.collect_bounds(BoundType::Deserialize)); @@ -67,11 +46,7 @@ pub fn struct_de(input: &ItemStruct, cratename: Ident) -> syn::Result syn::Result { let mut body = TokenStream2::new(); for (_field_idx, field) in fields.unnamed.iter().enumerate() { - let skipped = contains_skip(&field.attrs); + let skipped = field::contains_skip(&field.attrs); let parsed = field::Attributes::parse(&field.attrs, skipped)?; override_predicates.extend(parsed.collect_bounds(BoundType::Deserialize)); let needs_bounds_derive = parsed.needs_bounds_derive(BoundType::Deserialize); @@ -96,7 +71,7 @@ pub fn struct_de(input: &ItemStruct, cratename: Ident) -> syn::Result syn::Result syn::Result borsh::de::BorshDeserialize for A diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_de__tests__check_deserialize_with_attr.snap b/borsh-derive/src/internals/deserialize/structs/snapshots/check_deserialize_with_attr.snap similarity index 89% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_de__tests__check_deserialize_with_attr.snap rename to borsh-derive/src/internals/deserialize/structs/snapshots/check_deserialize_with_attr.snap index a20ab73d5..9e90ae158 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_de__tests__check_deserialize_with_attr.snap +++ b/borsh-derive/src/internals/deserialize/structs/snapshots/check_deserialize_with_attr.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/struct_de.rs +source: borsh-derive/src/internals/deserialize/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::de::BorshDeserialize for A diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_de__tests__generic_deserialize_bound.snap b/borsh-derive/src/internals/deserialize/structs/snapshots/generic_deserialize_bound.snap similarity index 90% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_de__tests__generic_deserialize_bound.snap rename to borsh-derive/src/internals/deserialize/structs/snapshots/generic_deserialize_bound.snap index 05587ce15..5e1b097ad 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_de__tests__generic_deserialize_bound.snap +++ b/borsh-derive/src/internals/deserialize/structs/snapshots/generic_deserialize_bound.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/struct_de.rs +source: borsh-derive/src/internals/deserialize/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::de::BorshDeserialize for C diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_de__tests__generic_named_fields_struct_borsh_skip.snap b/borsh-derive/src/internals/deserialize/structs/snapshots/generic_named_fields_struct_borsh_skip.snap similarity index 89% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_de__tests__generic_named_fields_struct_borsh_skip.snap rename to borsh-derive/src/internals/deserialize/structs/snapshots/generic_named_fields_struct_borsh_skip.snap index bfe7cfc2e..10fa5b362 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_de__tests__generic_named_fields_struct_borsh_skip.snap +++ b/borsh-derive/src/internals/deserialize/structs/snapshots/generic_named_fields_struct_borsh_skip.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/struct_de.rs +source: borsh-derive/src/internals/deserialize/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::de::BorshDeserialize for G diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_de__tests__generic_tuple_struct_borsh_skip1.snap b/borsh-derive/src/internals/deserialize/structs/snapshots/generic_tuple_struct_borsh_skip1.snap similarity index 90% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_de__tests__generic_tuple_struct_borsh_skip1.snap rename to borsh-derive/src/internals/deserialize/structs/snapshots/generic_tuple_struct_borsh_skip1.snap index 17512caa5..9af338b4b 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_de__tests__generic_tuple_struct_borsh_skip1.snap +++ b/borsh-derive/src/internals/deserialize/structs/snapshots/generic_tuple_struct_borsh_skip1.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/struct_de.rs +source: borsh-derive/src/internals/deserialize/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::de::BorshDeserialize for G diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_de__tests__generic_tuple_struct_borsh_skip2.snap b/borsh-derive/src/internals/deserialize/structs/snapshots/generic_tuple_struct_borsh_skip2.snap similarity index 90% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_de__tests__generic_tuple_struct_borsh_skip2.snap rename to borsh-derive/src/internals/deserialize/structs/snapshots/generic_tuple_struct_borsh_skip2.snap index a3694889d..2b7297394 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_de__tests__generic_tuple_struct_borsh_skip2.snap +++ b/borsh-derive/src/internals/deserialize/structs/snapshots/generic_tuple_struct_borsh_skip2.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/struct_de.rs +source: borsh-derive/src/internals/deserialize/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::de::BorshDeserialize for G diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_de__tests__override_automatically_added_default_trait.snap b/borsh-derive/src/internals/deserialize/structs/snapshots/override_automatically_added_default_trait.snap similarity index 89% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_de__tests__override_automatically_added_default_trait.snap rename to borsh-derive/src/internals/deserialize/structs/snapshots/override_automatically_added_default_trait.snap index 0fd245bef..9feb23149 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_de__tests__override_automatically_added_default_trait.snap +++ b/borsh-derive/src/internals/deserialize/structs/snapshots/override_automatically_added_default_trait.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/struct_de.rs +source: borsh-derive/src/internals/deserialize/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::de::BorshDeserialize for G1 diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_de__tests__recursive_struct.snap b/borsh-derive/src/internals/deserialize/structs/snapshots/recursive_struct.snap similarity index 87% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_de__tests__recursive_struct.snap rename to borsh-derive/src/internals/deserialize/structs/snapshots/recursive_struct.snap index 4203e8fdf..c3650b7aa 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_de__tests__recursive_struct.snap +++ b/borsh-derive/src/internals/deserialize/structs/snapshots/recursive_struct.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/struct_de.rs +source: borsh-derive/src/internals/deserialize/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::de::BorshDeserialize for CRecC { diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_de__tests__simple_generic_tuple_struct.snap b/borsh-derive/src/internals/deserialize/structs/snapshots/simple_generic_tuple_struct.snap similarity index 89% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_de__tests__simple_generic_tuple_struct.snap rename to borsh-derive/src/internals/deserialize/structs/snapshots/simple_generic_tuple_struct.snap index 7e285b521..865c62866 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_de__tests__simple_generic_tuple_struct.snap +++ b/borsh-derive/src/internals/deserialize/structs/snapshots/simple_generic_tuple_struct.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/struct_de.rs +source: borsh-derive/src/internals/deserialize/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::de::BorshDeserialize for TupleA diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_de__tests__simple_generics.snap b/borsh-derive/src/internals/deserialize/structs/snapshots/simple_generics.snap similarity index 89% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_de__tests__simple_generics.snap rename to borsh-derive/src/internals/deserialize/structs/snapshots/simple_generics.snap index cd778cb1a..bcf52d1b5 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_de__tests__simple_generics.snap +++ b/borsh-derive/src/internals/deserialize/structs/snapshots/simple_generics.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/struct_de.rs +source: borsh-derive/src/internals/deserialize/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::de::BorshDeserialize for A diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_de__tests__simple_struct.snap b/borsh-derive/src/internals/deserialize/structs/snapshots/simple_struct.snap similarity index 87% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_de__tests__simple_struct.snap rename to borsh-derive/src/internals/deserialize/structs/snapshots/simple_struct.snap index 087dcf563..2ce173615 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_de__tests__simple_struct.snap +++ b/borsh-derive/src/internals/deserialize/structs/snapshots/simple_struct.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/struct_de.rs +source: borsh-derive/src/internals/deserialize/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::de::BorshDeserialize for A { diff --git a/borsh-derive-internal/src/union_de.rs b/borsh-derive/src/internals/deserialize/unions/mod.rs similarity index 53% rename from borsh-derive-internal/src/union_de.rs rename to borsh-derive/src/internals/deserialize/unions/mod.rs index 768b84e13..cec91db74 100644 --- a/borsh-derive-internal/src/union_de.rs +++ b/borsh-derive/src/internals/deserialize/unions/mod.rs @@ -1,6 +1,6 @@ use proc_macro2::TokenStream as TokenStream2; use syn::{Ident, ItemUnion}; -pub fn union_de(_input: &ItemUnion, _cratename: Ident) -> syn::Result { +pub fn process(_input: &ItemUnion, _cratename: Ident) -> syn::Result { unimplemented!() } diff --git a/borsh-derive-internal/src/enum_discriminant_map.rs b/borsh-derive/src/internals/enum_discriminant.rs similarity index 89% rename from borsh-derive-internal/src/enum_discriminant_map.rs rename to borsh-derive/src/internals/enum_discriminant.rs index 5ecb1eefa..21c784c59 100644 --- a/borsh-derive-internal/src/enum_discriminant_map.rs +++ b/borsh-derive/src/internals/enum_discriminant.rs @@ -6,7 +6,7 @@ use syn::{punctuated::Punctuated, token::Comma, Variant}; /// Calculates the discriminant that will be assigned by the compiler. /// See: https://doc.rust-lang.org/reference/items/enumerations.html#assigning-discriminant-values -pub fn discriminant_map(variants: &Punctuated) -> HashMap { +pub fn map(variants: &Punctuated) -> HashMap { let mut map = HashMap::new(); let mut next_discriminant_if_not_specified = quote! {0}; diff --git a/borsh-schema-derive-internal/src/generics.rs b/borsh-derive/src/internals/generics.rs similarity index 99% rename from borsh-schema-derive-internal/src/generics.rs rename to borsh-derive/src/internals/generics.rs index 972de5b77..e3d5aaf35 100644 --- a/borsh-schema-derive-internal/src/generics.rs +++ b/borsh-derive/src/internals/generics.rs @@ -1,5 +1,3 @@ -// TODO: remove this unused attribute, when the unsplit is done -#![allow(unused)] use std::collections::{HashMap, HashSet}; use quote::{quote, ToTokens}; @@ -41,6 +39,7 @@ pub fn without_defaults(generics: &Generics) -> Generics { } } +#[cfg(feature = "schema")] pub fn type_contains_some_param(type_: &Type, params: &HashSet) -> bool { let mut find: FindTyParams = FindTyParams::from_params(params.iter()); @@ -90,16 +89,6 @@ impl FindTyParams { associated_type_params_usage: HashMap::new(), } } - pub fn from_params<'a>(params: impl Iterator) -> Self { - let all_type_params_ordered: Vec = params.cloned().collect(); - let all_type_params = all_type_params_ordered.clone().into_iter().collect(); - FindTyParams { - all_type_params, - all_type_params_ordered, - relevant_type_params: HashSet::new(), - associated_type_params_usage: HashMap::new(), - } - } pub fn process_for_bounds(self) -> Vec { let relevant_type_params = self.relevant_type_params; let associated_type_params_usage = self.associated_type_params_usage; @@ -131,6 +120,21 @@ impl FindTyParams { new_predicates } +} + +#[cfg(feature = "schema")] +impl FindTyParams { + pub fn from_params<'a>(params: impl Iterator) -> Self { + let all_type_params_ordered: Vec = params.cloned().collect(); + let all_type_params = all_type_params_ordered.clone().into_iter().collect(); + FindTyParams { + all_type_params, + all_type_params_ordered, + relevant_type_params: HashSet::new(), + associated_type_params_usage: HashMap::new(), + } + } + pub fn process_for_params(self) -> Vec { let relevant_type_params = self.relevant_type_params; let associated_type_params_usage = self.associated_type_params_usage; diff --git a/borsh-derive/src/internals/mod.rs b/borsh-derive/src/internals/mod.rs new file mode 100644 index 000000000..a98c5be2f --- /dev/null +++ b/borsh-derive/src/internals/mod.rs @@ -0,0 +1,10 @@ +pub mod attributes; +pub mod deserialize; +mod enum_discriminant; +mod generics; +#[cfg(feature = "schema")] +pub mod schema; +pub mod serialize; + +#[cfg(test)] +mod test_helpers; diff --git a/borsh-schema-derive-internal/src/enum_schema.rs b/borsh-derive/src/internals/schema/enums/mod.rs similarity index 75% rename from borsh-schema-derive-internal/src/enum_schema.rs rename to borsh-derive/src/internals/schema/enums/mod.rs index d182a206c..f9659c101 100644 --- a/borsh-schema-derive-internal/src/enum_schema.rs +++ b/borsh-derive/src/internals/schema/enums/mod.rs @@ -1,26 +1,21 @@ -use std::collections::HashSet; - use proc_macro2::{Span, TokenStream as TokenStream2}; use quote::{quote, ToTokens}; +use std::collections::HashSet; use syn::{Fields, Ident, ItemEnum, ItemStruct, Path, Visibility, WhereClause}; -use crate::{ - generics::{compute_predicates, without_defaults, FindTyParams}, - schema_helpers::{declaration, filter_field_attrs, filter_used_params}, - struct_schema::{visit_struct_fields, visit_struct_fields_unconditional}, -}; +use crate::internals::{attributes::field, generics, schema}; fn transform_variant_fields(mut input: Fields) -> Fields { match input { Fields::Named(ref mut named) => { for field in &mut named.named { - let field_attrs = filter_field_attrs(field.attrs.drain(..)).collect::>(); + let field_attrs = field::filter_attrs(field.attrs.drain(..)).collect::>(); field.attrs = field_attrs; } } Fields::Unnamed(ref mut unnamed) => { for field in &mut unnamed.unnamed { - let field_attrs = filter_field_attrs(field.attrs.drain(..)).collect::>(); + let field_attrs = field::filter_attrs(field.attrs.drain(..)).collect::>(); field.attrs = field_attrs; } } @@ -29,10 +24,10 @@ fn transform_variant_fields(mut input: Fields) -> Fields { input } -pub fn process_enum(input: &ItemEnum, cratename: Ident) -> syn::Result { +pub fn process(input: &ItemEnum, cratename: Ident) -> syn::Result { let name = &input.ident; let name_str = name.to_token_stream().to_string(); - let generics = without_defaults(&input.generics); + let generics = generics::without_defaults(&input.generics); let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); let mut where_clause = where_clause.map_or_else( @@ -42,7 +37,7 @@ pub fn process_enum(input: &ItemEnum, cratename: Ident) -> syn::Result syn::Result>(); - let inner_struct_generics = filter_used_params(&generics, variant_not_skipped_params); + let inner_struct_generics = + schema::filter_used_params(&generics, variant_not_skipped_params); let (_impl_generics, inner_struct_ty_generics, _where_clause) = inner_struct_generics.split_for_impl(); @@ -102,13 +101,13 @@ pub fn process_enum(input: &ItemEnum, cratename: Ident) -> syn::Result syn::Result borsh::BorshSchema for A diff --git a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__enum_schema__tests__complex_enum_generics_borsh_skip_named_field.snap b/borsh-derive/src/internals/schema/enums/snapshots/complex_enum_generics_borsh_skip_named_field.snap similarity index 97% rename from borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__enum_schema__tests__complex_enum_generics_borsh_skip_named_field.snap rename to borsh-derive/src/internals/schema/enums/snapshots/complex_enum_generics_borsh_skip_named_field.snap index b51e90b85..de88b6046 100644 --- a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__enum_schema__tests__complex_enum_generics_borsh_skip_named_field.snap +++ b/borsh-derive/src/internals/schema/enums/snapshots/complex_enum_generics_borsh_skip_named_field.snap @@ -1,5 +1,5 @@ --- -source: borsh-schema-derive-internal/src/enum_schema.rs +source: borsh-derive/src/internals/schema/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::BorshSchema for A diff --git a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__enum_schema__tests__complex_enum_generics_borsh_skip_tuple_field.snap b/borsh-derive/src/internals/schema/enums/snapshots/complex_enum_generics_borsh_skip_tuple_field.snap similarity index 97% rename from borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__enum_schema__tests__complex_enum_generics_borsh_skip_tuple_field.snap rename to borsh-derive/src/internals/schema/enums/snapshots/complex_enum_generics_borsh_skip_tuple_field.snap index d6c383fdf..475e8df2f 100644 --- a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__enum_schema__tests__complex_enum_generics_borsh_skip_tuple_field.snap +++ b/borsh-derive/src/internals/schema/enums/snapshots/complex_enum_generics_borsh_skip_tuple_field.snap @@ -1,5 +1,5 @@ --- -source: borsh-schema-derive-internal/src/enum_schema.rs +source: borsh-derive/src/internals/schema/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::BorshSchema for A diff --git a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__enum_schema__tests__filter_foreign_attrs.snap b/borsh-derive/src/internals/schema/enums/snapshots/filter_foreign_attrs.snap similarity index 95% rename from borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__enum_schema__tests__filter_foreign_attrs.snap rename to borsh-derive/src/internals/schema/enums/snapshots/filter_foreign_attrs.snap index 000974752..8de5239be 100644 --- a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__enum_schema__tests__filter_foreign_attrs.snap +++ b/borsh-derive/src/internals/schema/enums/snapshots/filter_foreign_attrs.snap @@ -1,5 +1,5 @@ --- -source: borsh-schema-derive-internal/src/enum_schema.rs +source: borsh-derive/src/internals/schema/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::BorshSchema for A { diff --git a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__enum_schema__tests__generic_associated_type.snap b/borsh-derive/src/internals/schema/enums/snapshots/generic_associated_type.snap similarity index 97% rename from borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__enum_schema__tests__generic_associated_type.snap rename to borsh-derive/src/internals/schema/enums/snapshots/generic_associated_type.snap index 406a8b32b..1bbda8a11 100644 --- a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__enum_schema__tests__generic_associated_type.snap +++ b/borsh-derive/src/internals/schema/enums/snapshots/generic_associated_type.snap @@ -1,5 +1,5 @@ --- -source: borsh-schema-derive-internal/src/enum_schema.rs +source: borsh-derive/src/internals/schema/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::BorshSchema for EnumParametrized diff --git a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__enum_schema__tests__generic_associated_type_param_override.snap b/borsh-derive/src/internals/schema/enums/snapshots/generic_associated_type_param_override.snap similarity index 97% rename from borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__enum_schema__tests__generic_associated_type_param_override.snap rename to borsh-derive/src/internals/schema/enums/snapshots/generic_associated_type_param_override.snap index f103ee343..c3bc0d3cb 100644 --- a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__enum_schema__tests__generic_associated_type_param_override.snap +++ b/borsh-derive/src/internals/schema/enums/snapshots/generic_associated_type_param_override.snap @@ -1,5 +1,5 @@ --- -source: borsh-schema-derive-internal/src/enum_schema.rs +source: borsh-derive/src/internals/schema/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::BorshSchema for EnumParametrized diff --git a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__enum_schema__tests__generic_associated_type_param_override_conflict.snap b/borsh-derive/src/internals/schema/enums/snapshots/generic_associated_type_param_override_conflict.snap similarity index 52% rename from borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__enum_schema__tests__generic_associated_type_param_override_conflict.snap rename to borsh-derive/src/internals/schema/enums/snapshots/generic_associated_type_param_override_conflict.snap index 843c22271..d7d76f2b7 100644 --- a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__enum_schema__tests__generic_associated_type_param_override_conflict.snap +++ b/borsh-derive/src/internals/schema/enums/snapshots/generic_associated_type_param_override_conflict.snap @@ -1,6 +1,6 @@ --- -source: borsh-schema-derive-internal/src/enum_schema.rs -expression: err +source: borsh-derive/src/internals/schema/enums/mod.rs +expression: actual.unwrap_err() --- Error( "`borsh_skip` cannot be used at the same time as `schema(params = ...)`", diff --git a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__enum_schema__tests__recursive_enum.snap b/borsh-derive/src/internals/schema/enums/snapshots/recursive_enum.snap similarity index 96% rename from borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__enum_schema__tests__recursive_enum.snap rename to borsh-derive/src/internals/schema/enums/snapshots/recursive_enum.snap index e8f03d3a7..9aa4eb153 100644 --- a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__enum_schema__tests__recursive_enum.snap +++ b/borsh-derive/src/internals/schema/enums/snapshots/recursive_enum.snap @@ -1,5 +1,5 @@ --- -source: borsh-schema-derive-internal/src/enum_schema.rs +source: borsh-derive/src/internals/schema/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::BorshSchema for A diff --git a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__enum_schema__tests__simple_enum.snap b/borsh-derive/src/internals/schema/enums/snapshots/simple_enum.snap similarity index 95% rename from borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__enum_schema__tests__simple_enum.snap rename to borsh-derive/src/internals/schema/enums/snapshots/simple_enum.snap index 8e08fc647..afd1a9e24 100644 --- a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__enum_schema__tests__simple_enum.snap +++ b/borsh-derive/src/internals/schema/enums/snapshots/simple_enum.snap @@ -1,5 +1,5 @@ --- -source: borsh-schema-derive-internal/src/enum_schema.rs +source: borsh-derive/src/internals/schema/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::BorshSchema for A { diff --git a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__enum_schema__tests__single_field_enum.snap b/borsh-derive/src/internals/schema/enums/snapshots/single_field_enum.snap similarity index 93% rename from borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__enum_schema__tests__single_field_enum.snap rename to borsh-derive/src/internals/schema/enums/snapshots/single_field_enum.snap index 4df409dac..06ecf2013 100644 --- a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__enum_schema__tests__single_field_enum.snap +++ b/borsh-derive/src/internals/schema/enums/snapshots/single_field_enum.snap @@ -1,5 +1,5 @@ --- -source: borsh-schema-derive-internal/src/enum_schema.rs +source: borsh-derive/src/internals/schema/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::BorshSchema for A { diff --git a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__enum_schema__tests__trailing_comma_generics.snap b/borsh-derive/src/internals/schema/enums/snapshots/trailing_comma_generics.snap similarity index 96% rename from borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__enum_schema__tests__trailing_comma_generics.snap rename to borsh-derive/src/internals/schema/enums/snapshots/trailing_comma_generics.snap index 3ef03335f..2636746a2 100644 --- a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__enum_schema__tests__trailing_comma_generics.snap +++ b/borsh-derive/src/internals/schema/enums/snapshots/trailing_comma_generics.snap @@ -1,5 +1,5 @@ --- -source: borsh-schema-derive-internal/src/enum_schema.rs +source: borsh-derive/src/internals/schema/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::BorshSchema for Side diff --git a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__enum_schema__tests__with_funcs_attr.snap b/borsh-derive/src/internals/schema/enums/snapshots/with_funcs_attr.snap similarity index 96% rename from borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__enum_schema__tests__with_funcs_attr.snap rename to borsh-derive/src/internals/schema/enums/snapshots/with_funcs_attr.snap index 013d77b50..8b0c41e23 100644 --- a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__enum_schema__tests__with_funcs_attr.snap +++ b/borsh-derive/src/internals/schema/enums/snapshots/with_funcs_attr.snap @@ -1,5 +1,5 @@ --- -source: borsh-schema-derive-internal/src/enum_schema.rs +source: borsh-derive/src/internals/schema/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::BorshSchema for C diff --git a/borsh-derive/src/internals/schema/mod.rs b/borsh-derive/src/internals/schema/mod.rs new file mode 100644 index 000000000..36712c12d --- /dev/null +++ b/borsh-derive/src/internals/schema/mod.rs @@ -0,0 +1,137 @@ +use std::collections::HashSet; + +use proc_macro2::TokenStream as TokenStream2; +use quote::quote; +use syn::{ + punctuated::Punctuated, token::Comma, Field, Fields, GenericParam, Generics, Ident, Type, + WherePredicate, +}; + +use crate::internals::{attributes::field, generics}; + +pub mod enums; +pub mod structs; + +fn declaration(ident_str: &str, cratename: Ident, params_for_bounds: Vec) -> TokenStream2 { + // Generate function that returns the name of the type. + let mut declaration_params = vec![]; + for type_param in params_for_bounds { + declaration_params.push(quote! { + <#type_param>::declaration() + }); + } + if declaration_params.is_empty() { + quote! { + #ident_str.to_string() + } + } else { + quote! { + let params = #cratename::__private::maybestd::vec![#(#declaration_params),*]; + format!(r#"{}<{}>"#, #ident_str, params.join(", ")) + } + } +} + +fn filter_used_params(generics: &Generics, not_skipped_type_params: HashSet) -> Generics { + let new_params = generics + .params + .clone() + .into_iter() + .filter(|param| match param { + GenericParam::Lifetime(..) | GenericParam::Const(..) => true, + GenericParam::Type(ty_param) => not_skipped_type_params.contains(&ty_param.ident), + }) + .collect(); + + let mut where_clause = generics.where_clause.clone(); + where_clause = where_clause.map(|mut clause| { + let new_predicates: Punctuated = clause + .predicates + .iter() + .filter(|predicate| match predicate { + WherePredicate::Lifetime(..) => true, + WherePredicate::Type(predicate_type) => generics::type_contains_some_param( + &predicate_type.bounded_ty, + ¬_skipped_type_params, + ), + #[cfg_attr( + feature = "force_exhaustive_checks", + deny(non_exhaustive_omitted_patterns) + )] + _ => true, + }) + .cloned() + .collect(); + clause.predicates = new_predicates; + clause + }); + Generics { + params: new_params, + where_clause, + ..generics.clone() + } +} + +fn visit_field(field: &Field, visitor: &mut generics::FindTyParams) -> syn::Result<()> { + let skipped = field::contains_skip(&field.attrs); + let parsed = field::Attributes::parse(&field.attrs, skipped)?; + let needs_schema_params_derive = parsed.needs_schema_params_derive(); + let schema_attrs = parsed.schema; + if !skipped { + if needs_schema_params_derive { + visitor.visit_field(field); + } + // there's no need to override params when field is skipped, because when field is skipped + // derive for it doesn't attempt to add any bounds, unlike `BorshDeserialize`, which + // adds `Default` bound on any type parameters in skipped field + + if let Some(schema_attrs) = schema_attrs { + if let Some(schema_params) = schema_attrs.params { + for field::schema::ParameterOverride { + order_param, + override_type, + .. + } in schema_params + { + visitor.param_associated_type_insert(order_param, override_type); + } + } + } + } + Ok(()) +} + +/// check param usage in fields with respect to `borsh_skip` attribute usage +fn visit_struct_fields(fields: &Fields, visitor: &mut generics::FindTyParams) -> syn::Result<()> { + match &fields { + Fields::Named(fields) => { + for field in &fields.named { + visit_field(field, visitor)?; + } + } + Fields::Unnamed(fields) => { + for field in &fields.unnamed { + visit_field(field, visitor)?; + } + } + Fields::Unit => {} + } + Ok(()) +} + +/// check param usage in fields +fn visit_struct_fields_unconditional(fields: &Fields, visitor: &mut generics::FindTyParams) { + match &fields { + Fields::Named(fields) => { + for field in &fields.named { + visitor.visit_field(field); + } + } + Fields::Unnamed(fields) => { + for field in &fields.unnamed { + visitor.visit_field(field); + } + } + Fields::Unit => {} + } +} diff --git a/borsh-schema-derive-internal/src/struct_schema.rs b/borsh-derive/src/internals/schema/structs/mod.rs similarity index 68% rename from borsh-schema-derive-internal/src/struct_schema.rs rename to borsh-derive/src/internals/schema/structs/mod.rs index b110478c8..4ef3dc2ce 100644 --- a/borsh-schema-derive-internal/src/struct_schema.rs +++ b/borsh-derive/src/internals/schema/structs/mod.rs @@ -1,20 +1,13 @@ use proc_macro2::TokenStream as TokenStream2; use quote::{quote, ToTokens}; -use syn::{ExprPath, Field, Fields, Ident, ItemStruct, Path, Type, WhereClause}; +use syn::{ExprPath, Fields, Ident, ItemStruct, Path, Type, WhereClause}; -use crate::{ - attribute_helpers::{ - contains_skip, - field::{self, schema}, - }, - generics::{compute_predicates, without_defaults, FindTyParams}, - schema_helpers::declaration, -}; +use crate::internals::{attributes::field, generics, schema}; /// function which computes derive output [proc_macro2::TokenStream] /// of code, which computes declaration of a single field, which is later added to /// the struct's definition as a whole -pub(crate) fn field_declaration_output( +fn field_declaration_output( field_name: Option<&String>, field_type: &Type, cratename: &Ident, @@ -38,7 +31,7 @@ pub(crate) fn field_declaration_output( /// function which computes derive output [proc_macro2::TokenStream] /// of code, which adds definitions of a field to the output `definitions: &mut BTreeMap` -pub(crate) fn field_definitions_output( +fn field_definitions_output( field_type: &Type, cratename: &Ident, definitions_override: Option, @@ -54,74 +47,10 @@ pub(crate) fn field_definitions_output( } } -fn visit_field(field: &Field, visitor: &mut FindTyParams) -> syn::Result<()> { - let skipped = contains_skip(&field.attrs); - let parsed = field::Attributes::parse(&field.attrs, skipped)?; - let needs_schema_params_derive = parsed.needs_schema_params_derive(); - let schema_attrs = parsed.schema; - if !skipped { - if needs_schema_params_derive { - visitor.visit_field(field); - } - // there's no need to override params when field is skipped, because when field is skipped - // derive for it doesn't attempt to add any bounds, unlike `BorshDeserialize`, which - // adds `Default` bound on any type parameters in skipped field - - if let Some(schema_attrs) = schema_attrs { - if let Some(schema_params) = schema_attrs.params { - for schema::ParameterOverride { - order_param, - override_type, - .. - } in schema_params - { - visitor.param_associated_type_insert(order_param, override_type); - } - } - } - } - Ok(()) -} - -/// check param usage in fields with respect to `borsh_skip` attribute usage -pub fn visit_struct_fields(fields: &Fields, visitor: &mut FindTyParams) -> syn::Result<()> { - match &fields { - Fields::Named(fields) => { - for field in &fields.named { - visit_field(field, visitor)?; - } - } - Fields::Unnamed(fields) => { - for field in &fields.unnamed { - visit_field(field, visitor)?; - } - } - Fields::Unit => {} - } - Ok(()) -} - -/// check param usage in fields -pub fn visit_struct_fields_unconditional(fields: &Fields, visitor: &mut FindTyParams) { - match &fields { - Fields::Named(fields) => { - for field in &fields.named { - visitor.visit_field(field); - } - } - Fields::Unnamed(fields) => { - for field in &fields.unnamed { - visitor.visit_field(field); - } - } - Fields::Unit => {} - } -} - -pub fn process_struct(input: &ItemStruct, cratename: Ident) -> syn::Result { +pub fn process(input: &ItemStruct, cratename: Ident) -> syn::Result { let name = &input.ident; let name_str = name.to_token_stream().to_string(); - let generics = without_defaults(&input.generics); + let generics = generics::without_defaults(&input.generics); let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); let mut where_clause = where_clause.map_or_else( @@ -132,17 +61,17 @@ pub fn process_struct(input: &ItemStruct, cratename: Ident) -> syn::Result { for field in &fields.named { - let skipped = contains_skip(&field.attrs); + let skipped = field::contains_skip(&field.attrs); let parsed = field::Attributes::parse(&field.attrs, skipped)?; if skipped { continue; @@ -169,7 +98,7 @@ pub fn process_struct(input: &ItemStruct, cratename: Ident) -> syn::Result { for field in &fields.unnamed { - let skipped = contains_skip(&field.attrs); + let skipped = field::contains_skip(&field.attrs); let parsed = field::Attributes::parse(&field.attrs, skipped)?; if skipped { continue; @@ -216,14 +145,14 @@ pub fn process_struct(input: &ItemStruct, cratename: Ident) -> syn::Result syn::Result borsh::BorshSchema for Parametrized diff --git a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__generic_associated_type_param_override.snap b/borsh-derive/src/internals/schema/structs/snapshots/generic_associated_type_param_override.snap similarity index 96% rename from borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__generic_associated_type_param_override.snap rename to borsh-derive/src/internals/schema/structs/snapshots/generic_associated_type_param_override.snap index 303a6a90d..c42b7677f 100644 --- a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__generic_associated_type_param_override.snap +++ b/borsh-derive/src/internals/schema/structs/snapshots/generic_associated_type_param_override.snap @@ -1,5 +1,5 @@ --- -source: borsh-schema-derive-internal/src/struct_schema.rs +source: borsh-derive/src/internals/schema/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::BorshSchema for Parametrized diff --git a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__generic_associated_type_param_override2.snap b/borsh-derive/src/internals/schema/structs/snapshots/generic_associated_type_param_override2.snap similarity index 96% rename from borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__generic_associated_type_param_override2.snap rename to borsh-derive/src/internals/schema/structs/snapshots/generic_associated_type_param_override2.snap index 3e47f73dc..b09937702 100644 --- a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__generic_associated_type_param_override2.snap +++ b/borsh-derive/src/internals/schema/structs/snapshots/generic_associated_type_param_override2.snap @@ -1,5 +1,5 @@ --- -source: borsh-schema-derive-internal/src/struct_schema.rs +source: borsh-derive/src/internals/schema/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::BorshSchema for Parametrized diff --git a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__generic_associated_type_param_override_conflict.snap b/borsh-derive/src/internals/schema/structs/snapshots/generic_associated_type_param_override_conflict.snap similarity index 51% rename from borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__generic_associated_type_param_override_conflict.snap rename to borsh-derive/src/internals/schema/structs/snapshots/generic_associated_type_param_override_conflict.snap index 2a05e5cf2..ecf0512bc 100644 --- a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__generic_associated_type_param_override_conflict.snap +++ b/borsh-derive/src/internals/schema/structs/snapshots/generic_associated_type_param_override_conflict.snap @@ -1,6 +1,6 @@ --- -source: borsh-schema-derive-internal/src/struct_schema.rs -expression: err +source: borsh-derive/src/internals/schema/structs/mod.rs +expression: actual.unwrap_err() --- Error( "`borsh_skip` cannot be used at the same time as `schema(params = ...)`", diff --git a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__generic_named_fields_struct_borsh_skip.snap b/borsh-derive/src/internals/schema/structs/snapshots/generic_named_fields_struct_borsh_skip.snap similarity index 95% rename from borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__generic_named_fields_struct_borsh_skip.snap rename to borsh-derive/src/internals/schema/structs/snapshots/generic_named_fields_struct_borsh_skip.snap index e79e5932a..cd826d92d 100644 --- a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__generic_named_fields_struct_borsh_skip.snap +++ b/borsh-derive/src/internals/schema/structs/snapshots/generic_named_fields_struct_borsh_skip.snap @@ -1,5 +1,5 @@ --- -source: borsh-schema-derive-internal/src/struct_schema.rs +source: borsh-derive/src/internals/schema/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::BorshSchema for G diff --git a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__generic_tuple_struct_borsh_skip1.snap b/borsh-derive/src/internals/schema/structs/snapshots/generic_tuple_struct_borsh_skip1.snap similarity index 94% rename from borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__generic_tuple_struct_borsh_skip1.snap rename to borsh-derive/src/internals/schema/structs/snapshots/generic_tuple_struct_borsh_skip1.snap index 8d68ab062..654f77ed3 100644 --- a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__generic_tuple_struct_borsh_skip1.snap +++ b/borsh-derive/src/internals/schema/structs/snapshots/generic_tuple_struct_borsh_skip1.snap @@ -1,5 +1,5 @@ --- -source: borsh-schema-derive-internal/src/struct_schema.rs +source: borsh-derive/src/internals/schema/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::BorshSchema for G diff --git a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__generic_tuple_struct_borsh_skip2.snap b/borsh-derive/src/internals/schema/structs/snapshots/generic_tuple_struct_borsh_skip2.snap similarity index 95% rename from borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__generic_tuple_struct_borsh_skip2.snap rename to borsh-derive/src/internals/schema/structs/snapshots/generic_tuple_struct_borsh_skip2.snap index 1a31a66f2..03f2b45c0 100644 --- a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__generic_tuple_struct_borsh_skip2.snap +++ b/borsh-derive/src/internals/schema/structs/snapshots/generic_tuple_struct_borsh_skip2.snap @@ -1,5 +1,5 @@ --- -source: borsh-schema-derive-internal/src/struct_schema.rs +source: borsh-derive/src/internals/schema/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::BorshSchema for G diff --git a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__generic_tuple_struct_borsh_skip3.snap b/borsh-derive/src/internals/schema/structs/snapshots/generic_tuple_struct_borsh_skip3.snap similarity index 95% rename from borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__generic_tuple_struct_borsh_skip3.snap rename to borsh-derive/src/internals/schema/structs/snapshots/generic_tuple_struct_borsh_skip3.snap index cfe50b4e6..3364136c6 100644 --- a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__generic_tuple_struct_borsh_skip3.snap +++ b/borsh-derive/src/internals/schema/structs/snapshots/generic_tuple_struct_borsh_skip3.snap @@ -1,5 +1,5 @@ --- -source: borsh-schema-derive-internal/src/struct_schema.rs +source: borsh-derive/src/internals/schema/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::BorshSchema for G diff --git a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__generic_tuple_struct_borsh_skip4.snap b/borsh-derive/src/internals/schema/structs/snapshots/generic_tuple_struct_borsh_skip4.snap similarity index 95% rename from borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__generic_tuple_struct_borsh_skip4.snap rename to borsh-derive/src/internals/schema/structs/snapshots/generic_tuple_struct_borsh_skip4.snap index 653e0da29..8fae50a06 100644 --- a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__generic_tuple_struct_borsh_skip4.snap +++ b/borsh-derive/src/internals/schema/structs/snapshots/generic_tuple_struct_borsh_skip4.snap @@ -1,5 +1,5 @@ --- -source: borsh-schema-derive-internal/src/struct_schema.rs +source: borsh-derive/src/internals/schema/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::BorshSchema for ASalad { diff --git a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__recursive_struct.snap b/borsh-derive/src/internals/schema/structs/snapshots/recursive_struct.snap similarity index 95% rename from borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__recursive_struct.snap rename to borsh-derive/src/internals/schema/structs/snapshots/recursive_struct.snap index 71b773466..d59ade89d 100644 --- a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__recursive_struct.snap +++ b/borsh-derive/src/internals/schema/structs/snapshots/recursive_struct.snap @@ -1,5 +1,5 @@ --- -source: borsh-schema-derive-internal/src/struct_schema.rs +source: borsh-derive/src/internals/schema/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::BorshSchema for CRecC { diff --git a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__schema_param_override3.snap b/borsh-derive/src/internals/schema/structs/snapshots/schema_param_override3.snap similarity index 96% rename from borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__schema_param_override3.snap rename to borsh-derive/src/internals/schema/structs/snapshots/schema_param_override3.snap index 05bb2afc9..d768917d1 100644 --- a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__schema_param_override3.snap +++ b/borsh-derive/src/internals/schema/structs/snapshots/schema_param_override3.snap @@ -1,5 +1,5 @@ --- -source: borsh-schema-derive-internal/src/struct_schema.rs +source: borsh-derive/src/internals/schema/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::BorshSchema for A diff --git a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__simple_generics.snap b/borsh-derive/src/internals/schema/structs/snapshots/simple_generics.snap similarity index 96% rename from borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__simple_generics.snap rename to borsh-derive/src/internals/schema/structs/snapshots/simple_generics.snap index 86c462939..4217ea299 100644 --- a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__simple_generics.snap +++ b/borsh-derive/src/internals/schema/structs/snapshots/simple_generics.snap @@ -1,5 +1,5 @@ --- -source: borsh-schema-derive-internal/src/struct_schema.rs +source: borsh-derive/src/internals/schema/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::BorshSchema for A diff --git a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__simple_struct.snap b/borsh-derive/src/internals/schema/structs/snapshots/simple_struct.snap similarity index 95% rename from borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__simple_struct.snap rename to borsh-derive/src/internals/schema/structs/snapshots/simple_struct.snap index 68119d5ad..85f3ea732 100644 --- a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__simple_struct.snap +++ b/borsh-derive/src/internals/schema/structs/snapshots/simple_struct.snap @@ -1,5 +1,5 @@ --- -source: borsh-schema-derive-internal/src/struct_schema.rs +source: borsh-derive/src/internals/schema/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::BorshSchema for A { diff --git a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__trailing_comma_generics.snap b/borsh-derive/src/internals/schema/structs/snapshots/trailing_comma_generics.snap similarity index 96% rename from borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__trailing_comma_generics.snap rename to borsh-derive/src/internals/schema/structs/snapshots/trailing_comma_generics.snap index 6073b71f7..496d19831 100644 --- a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__trailing_comma_generics.snap +++ b/borsh-derive/src/internals/schema/structs/snapshots/trailing_comma_generics.snap @@ -1,5 +1,5 @@ --- -source: borsh-schema-derive-internal/src/struct_schema.rs +source: borsh-derive/src/internals/schema/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::BorshSchema for A diff --git a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__tuple_struct.snap b/borsh-derive/src/internals/schema/structs/snapshots/tuple_struct.snap similarity index 95% rename from borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__tuple_struct.snap rename to borsh-derive/src/internals/schema/structs/snapshots/tuple_struct.snap index 386ce8315..66629e4cf 100644 --- a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__tuple_struct.snap +++ b/borsh-derive/src/internals/schema/structs/snapshots/tuple_struct.snap @@ -1,5 +1,5 @@ --- -source: borsh-schema-derive-internal/src/struct_schema.rs +source: borsh-derive/src/internals/schema/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::BorshSchema for A { diff --git a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__tuple_struct_params.snap b/borsh-derive/src/internals/schema/structs/snapshots/tuple_struct_params.snap similarity index 95% rename from borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__tuple_struct_params.snap rename to borsh-derive/src/internals/schema/structs/snapshots/tuple_struct_params.snap index fef5017c0..9a7b0466d 100644 --- a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__tuple_struct_params.snap +++ b/borsh-derive/src/internals/schema/structs/snapshots/tuple_struct_params.snap @@ -1,5 +1,5 @@ --- -source: borsh-schema-derive-internal/src/struct_schema.rs +source: borsh-derive/src/internals/schema/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::BorshSchema for A diff --git a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__tuple_struct_partial_skip.snap b/borsh-derive/src/internals/schema/structs/snapshots/tuple_struct_partial_skip.snap similarity index 94% rename from borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__tuple_struct_partial_skip.snap rename to borsh-derive/src/internals/schema/structs/snapshots/tuple_struct_partial_skip.snap index 398acbc68..d1a9b867a 100644 --- a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__tuple_struct_partial_skip.snap +++ b/borsh-derive/src/internals/schema/structs/snapshots/tuple_struct_partial_skip.snap @@ -1,5 +1,5 @@ --- -source: borsh-schema-derive-internal/src/struct_schema.rs +source: borsh-derive/src/internals/schema/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::BorshSchema for A { diff --git a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__unit_struct.snap b/borsh-derive/src/internals/schema/structs/snapshots/tuple_struct_whole_skip.snap similarity index 92% rename from borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__unit_struct.snap rename to borsh-derive/src/internals/schema/structs/snapshots/tuple_struct_whole_skip.snap index 40a2c290c..302705d3c 100644 --- a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__unit_struct.snap +++ b/borsh-derive/src/internals/schema/structs/snapshots/tuple_struct_whole_skip.snap @@ -1,5 +1,5 @@ --- -source: borsh-schema-derive-internal/src/struct_schema.rs +source: borsh-derive/src/internals/schema/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::BorshSchema for A { diff --git a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__tuple_struct_whole_skip.snap b/borsh-derive/src/internals/schema/structs/snapshots/unit_struct.snap similarity index 92% rename from borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__tuple_struct_whole_skip.snap rename to borsh-derive/src/internals/schema/structs/snapshots/unit_struct.snap index 40a2c290c..302705d3c 100644 --- a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__tuple_struct_whole_skip.snap +++ b/borsh-derive/src/internals/schema/structs/snapshots/unit_struct.snap @@ -1,5 +1,5 @@ --- -source: borsh-schema-derive-internal/src/struct_schema.rs +source: borsh-derive/src/internals/schema/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::BorshSchema for A { diff --git a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__with_funcs_attr.snap b/borsh-derive/src/internals/schema/structs/snapshots/with_funcs_attr.snap similarity index 95% rename from borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__with_funcs_attr.snap rename to borsh-derive/src/internals/schema/structs/snapshots/with_funcs_attr.snap index 31905697e..d737c5510 100644 --- a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__with_funcs_attr.snap +++ b/borsh-derive/src/internals/schema/structs/snapshots/with_funcs_attr.snap @@ -1,5 +1,5 @@ --- -source: borsh-schema-derive-internal/src/struct_schema.rs +source: borsh-derive/src/internals/schema/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::BorshSchema for A diff --git a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__wrapper_struct.snap b/borsh-derive/src/internals/schema/structs/snapshots/wrapper_struct.snap similarity index 94% rename from borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__wrapper_struct.snap rename to borsh-derive/src/internals/schema/structs/snapshots/wrapper_struct.snap index 617b595a4..9065efabd 100644 --- a/borsh-schema-derive-internal/src/snapshots/borsh_schema_derive_internal__struct_schema__tests__wrapper_struct.snap +++ b/borsh-derive/src/internals/schema/structs/snapshots/wrapper_struct.snap @@ -1,5 +1,5 @@ --- -source: borsh-schema-derive-internal/src/struct_schema.rs +source: borsh-derive/src/internals/schema/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::BorshSchema for A diff --git a/borsh-derive-internal/src/enum_ser.rs b/borsh-derive/src/internals/serialize/enums/mod.rs similarity index 77% rename from borsh-derive-internal/src/enum_ser.rs rename to borsh-derive/src/internals/serialize/enums/mod.rs index ba937e841..fca5f89fe 100644 --- a/borsh-derive-internal/src/enum_ser.rs +++ b/borsh-derive/src/internals/serialize/enums/mod.rs @@ -6,16 +6,14 @@ use syn::{ Expr, Fields, FieldsNamed, FieldsUnnamed, Ident, ItemEnum, Path, WhereClause, WherePredicate, }; -use crate::{ - attribute_helpers::{contains_skip, contains_use_discriminant, field, BoundType}, - enum_discriminant_map::discriminant_map, - generics::{compute_predicates, without_defaults, FindTyParams}, - struct_ser::field_serialization_output, +use crate::internals::{ + attributes::{field, item, BoundType}, + enum_discriminant, generics, serialize, }; -pub fn enum_ser(input: &ItemEnum, cratename: Ident) -> syn::Result { +pub fn process(input: &ItemEnum, cratename: Ident) -> syn::Result { let enum_ident = &input.ident; - let generics = without_defaults(&input.generics); + let generics = generics::without_defaults(&input.generics); let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); let mut where_clause = where_clause.map_or_else( || WhereClause { @@ -25,13 +23,13 @@ pub fn enum_ser(input: &ItemEnum, cratename: Ident) -> syn::Result Clone::clone, ); - let mut serialize_params_visitor = FindTyParams::new(&generics); + let mut serialize_params_visitor = generics::FindTyParams::new(&generics); let mut override_predicates = vec![]; - let use_discriminant = contains_use_discriminant(input)?; + let use_discriminant = item::contains_use_discriminant(input)?; let mut all_variants_idx_body = TokenStream2::new(); let mut fields_body = TokenStream2::new(); - let discriminants = discriminant_map(&input.variants); + let discriminants = enum_discriminant::map(&input.variants); for (variant_idx, variant) in input.variants.iter().enumerate() { let variant_idx = u8::try_from(variant_idx).map_err(|err| { @@ -104,7 +102,8 @@ pub fn enum_ser(input: &ItemEnum, cratename: Ident) -> syn::Result )) } let trait_path: Path = syn::parse2(quote! { #cratename::ser::BorshSerialize }).unwrap(); - let predicates = compute_predicates(serialize_params_visitor.process_for_bounds(), &trait_path); + let predicates = + generics::compute_predicates(serialize_params_visitor.process_for_bounds(), &trait_path); where_clause.predicates.extend(predicates); where_clause.predicates.extend(override_predicates); Ok(quote! { @@ -131,13 +130,13 @@ struct VariantParts { fn named_fields( cratename: &Ident, fields: &FieldsNamed, - params_visitor: &mut FindTyParams, + params_visitor: &mut generics::FindTyParams, override_output: &mut Vec, ) -> syn::Result { let mut variant_header = TokenStream2::new(); let mut variant_body = TokenStream2::new(); for field in &fields.named { - let skipped = contains_skip(&field.attrs); + let skipped = field::contains_skip(&field.attrs); let parsed = field::Attributes::parse(&field.attrs, skipped)?; let needs_bounds_derive = parsed.needs_bounds_derive(BoundType::Serialize); @@ -148,7 +147,7 @@ fn named_fields( variant_header.extend(quote! { #field_ident, }); let arg: Expr = syn::parse2(quote! { #field_ident }).unwrap(); - let delta = field_serialization_output(&arg, cratename, parsed.serialize_with); + let delta = serialize::field_output(&arg, cratename, parsed.serialize_with); variant_body.extend(delta); if needs_bounds_derive { params_visitor.visit_field(field); @@ -166,13 +165,13 @@ fn named_fields( fn unnamed_fields( cratename: &Ident, fields: &FieldsUnnamed, - params_visitor: &mut FindTyParams, + params_visitor: &mut generics::FindTyParams, override_output: &mut Vec, ) -> syn::Result { let mut variant_header = TokenStream2::new(); let mut variant_body = TokenStream2::new(); for (field_idx, field) in fields.unnamed.iter().enumerate() { - let skipped = contains_skip(&field.attrs); + let skipped = field::contains_skip(&field.attrs); let parsed = field::Attributes::parse(&field.attrs, skipped)?; let needs_bounds_derive = parsed.needs_bounds_derive(BoundType::Serialize); override_output.extend(parsed.collect_bounds(BoundType::Serialize)); @@ -186,7 +185,7 @@ fn unnamed_fields( variant_header.extend(quote! { #field_ident, }); let arg: Expr = syn::parse2(quote! { #field_ident }).unwrap(); - let delta = field_serialization_output(&arg, cratename, parsed.serialize_with); + let delta = serialize::field_output(&arg, cratename, parsed.serialize_with); variant_body.extend(delta); if needs_bounds_derive { params_visitor.visit_field(field); @@ -202,7 +201,7 @@ fn unnamed_fields( #[cfg(test)] mod tests { - use crate::test_helpers::pretty_print_syn_str; + use crate::internals::test_helpers::{local_insta_assert_snapshot, pretty_print_syn_str}; use super::*; use proc_macro2::Span; @@ -218,9 +217,9 @@ mod tests { } }) .unwrap(); - let actual = enum_ser(&item_enum, Ident::new("borsh", Span::call_site())).unwrap(); + let actual = process(&item_enum, Ident::new("borsh", Span::call_site())).unwrap(); - insta::assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); + local_insta_assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); } #[test] @@ -239,9 +238,9 @@ mod tests { }) .unwrap(); - let actual = enum_ser(&item_enum, Ident::new("borsh", Span::call_site())).unwrap(); + let actual = process(&item_enum, Ident::new("borsh", Span::call_site())).unwrap(); - insta::assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); + local_insta_assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); } #[test] @@ -263,9 +262,9 @@ mod tests { }) .unwrap(); - let actual = enum_ser(&item_enum, Ident::new("borsh", Span::call_site())).unwrap(); + let actual = process(&item_enum, Ident::new("borsh", Span::call_site())).unwrap(); - insta::assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); + local_insta_assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); } #[test] @@ -288,9 +287,9 @@ mod tests { }) .unwrap(); - let actual = enum_ser(&item_enum, Ident::new("borsh", Span::call_site())).unwrap(); + let actual = process(&item_enum, Ident::new("borsh", Span::call_site())).unwrap(); - insta::assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); + local_insta_assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); } #[test] @@ -306,8 +305,8 @@ mod tests { }) .unwrap(); - let actual = enum_ser(&item_struct, Ident::new("borsh", Span::call_site())).unwrap(); - insta::assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); + let actual = process(&item_struct, Ident::new("borsh", Span::call_site())).unwrap(); + local_insta_assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); } #[test] @@ -323,8 +322,8 @@ mod tests { }) .unwrap(); - let actual = enum_ser(&item_struct, Ident::new("borsh", Span::call_site())).unwrap(); - insta::assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); + let actual = process(&item_struct, Ident::new("borsh", Span::call_site())).unwrap(); + local_insta_assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); } #[test] @@ -340,9 +339,9 @@ mod tests { }) .unwrap(); - let actual = enum_ser(&item_struct, Ident::new("borsh", Span::call_site())).unwrap(); + let actual = process(&item_struct, Ident::new("borsh", Span::call_site())).unwrap(); - insta::assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); + local_insta_assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); } #[test] @@ -359,9 +358,9 @@ mod tests { }) .unwrap(); - let actual = enum_ser(&item_struct, Ident::new("borsh", Span::call_site())).unwrap(); + let actual = process(&item_struct, Ident::new("borsh", Span::call_site())).unwrap(); - insta::assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); + local_insta_assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); } #[test] @@ -377,9 +376,9 @@ mod tests { }) .unwrap(); - let actual = enum_ser(&item_struct, Ident::new("borsh", Span::call_site())).unwrap(); + let actual = process(&item_struct, Ident::new("borsh", Span::call_site())).unwrap(); - insta::assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); + local_insta_assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); } #[test] @@ -399,9 +398,9 @@ mod tests { }) .unwrap(); - let actual = enum_ser(&item_struct, Ident::new("borsh", Span::call_site())).unwrap(); + let actual = process(&item_struct, Ident::new("borsh", Span::call_site())).unwrap(); - insta::assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); + local_insta_assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); } #[test] @@ -418,9 +417,9 @@ mod tests { }) .unwrap(); - let actual = enum_ser(&item_struct, Ident::new("borsh", Span::call_site())).unwrap(); + let actual = process(&item_struct, Ident::new("borsh", Span::call_site())).unwrap(); - insta::assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); + local_insta_assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); } #[test] @@ -437,9 +436,9 @@ mod tests { } }) .unwrap(); - let actual = enum_ser(&item_enum, Ident::new("borsh", Span::call_site())).unwrap(); + let actual = process(&item_enum, Ident::new("borsh", Span::call_site())).unwrap(); - insta::assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); + local_insta_assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); } #[test] fn borsh_discriminant_true() { @@ -455,8 +454,8 @@ mod tests { } }) .unwrap(); - let actual = enum_ser(&item_enum, Ident::new("borsh", Span::call_site())).unwrap(); + let actual = process(&item_enum, Ident::new("borsh", Span::call_site())).unwrap(); - insta::assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); + local_insta_assert_snapshot!(pretty_print_syn_str(&actual).unwrap()); } } diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__borsh_discriminant_false.snap b/borsh-derive/src/internals/serialize/enums/snapshots/borsh_discriminant_false.snap similarity index 92% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__borsh_discriminant_false.snap rename to borsh-derive/src/internals/serialize/enums/snapshots/borsh_discriminant_false.snap index 97aeb1d77..23980eaec 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__borsh_discriminant_false.snap +++ b/borsh-derive/src/internals/serialize/enums/snapshots/borsh_discriminant_false.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/enum_ser.rs +source: borsh-derive/src/internals/serialize/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::ser::BorshSerialize for X { diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__borsh_discriminant_true.snap b/borsh-derive/src/internals/serialize/enums/snapshots/borsh_discriminant_true.snap similarity index 92% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__borsh_discriminant_true.snap rename to borsh-derive/src/internals/serialize/enums/snapshots/borsh_discriminant_true.snap index e0e43a55b..9d533f2ae 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__borsh_discriminant_true.snap +++ b/borsh-derive/src/internals/serialize/enums/snapshots/borsh_discriminant_true.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/enum_ser.rs +source: borsh-derive/src/internals/serialize/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::ser::BorshSerialize for X { diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__borsh_skip_struct_variant_all_fields.snap b/borsh-derive/src/internals/serialize/enums/snapshots/borsh_skip_struct_variant_all_fields.snap similarity index 92% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__borsh_skip_struct_variant_all_fields.snap rename to borsh-derive/src/internals/serialize/enums/snapshots/borsh_skip_struct_variant_all_fields.snap index 5f4b9d530..353683d0a 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__borsh_skip_struct_variant_all_fields.snap +++ b/borsh-derive/src/internals/serialize/enums/snapshots/borsh_skip_struct_variant_all_fields.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/enum_ser.rs +source: borsh-derive/src/internals/serialize/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::ser::BorshSerialize for AAB { diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__borsh_skip_struct_variant_field.snap b/borsh-derive/src/internals/serialize/enums/snapshots/borsh_skip_struct_variant_field.snap similarity index 92% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__borsh_skip_struct_variant_field.snap rename to borsh-derive/src/internals/serialize/enums/snapshots/borsh_skip_struct_variant_field.snap index bda423c4e..4b990a64d 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__borsh_skip_struct_variant_field.snap +++ b/borsh-derive/src/internals/serialize/enums/snapshots/borsh_skip_struct_variant_field.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/enum_ser.rs +source: borsh-derive/src/internals/serialize/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::ser::BorshSerialize for AB { diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__borsh_skip_tuple_variant_field.snap b/borsh-derive/src/internals/serialize/enums/snapshots/borsh_skip_tuple_variant_field.snap similarity index 92% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__borsh_skip_tuple_variant_field.snap rename to borsh-derive/src/internals/serialize/enums/snapshots/borsh_skip_tuple_variant_field.snap index 2b4fd55cc..12c7d5083 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__borsh_skip_tuple_variant_field.snap +++ b/borsh-derive/src/internals/serialize/enums/snapshots/borsh_skip_tuple_variant_field.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/enum_ser.rs +source: borsh-derive/src/internals/serialize/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::ser::BorshSerialize for AATTB { diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__bound_generics.snap b/borsh-derive/src/internals/serialize/enums/snapshots/bound_generics.snap similarity index 94% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__bound_generics.snap rename to borsh-derive/src/internals/serialize/enums/snapshots/bound_generics.snap index 6f6567f45..52e0aca84 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__bound_generics.snap +++ b/borsh-derive/src/internals/serialize/enums/snapshots/bound_generics.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/enum_ser.rs +source: borsh-derive/src/internals/serialize/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::ser::BorshSerialize for A diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__check_serialize_with_attr.snap b/borsh-derive/src/internals/serialize/enums/snapshots/check_serialize_with_attr.snap similarity index 94% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__check_serialize_with_attr.snap rename to borsh-derive/src/internals/serialize/enums/snapshots/check_serialize_with_attr.snap index e2d02962b..08d13aeff 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__check_serialize_with_attr.snap +++ b/borsh-derive/src/internals/serialize/enums/snapshots/check_serialize_with_attr.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/enum_ser.rs +source: borsh-derive/src/internals/serialize/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::ser::BorshSerialize for C diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__generic_borsh_skip_struct_field.snap b/borsh-derive/src/internals/serialize/enums/snapshots/generic_borsh_skip_struct_field.snap similarity index 93% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__generic_borsh_skip_struct_field.snap rename to borsh-derive/src/internals/serialize/enums/snapshots/generic_borsh_skip_struct_field.snap index 5340ae530..4c6e92494 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__generic_borsh_skip_struct_field.snap +++ b/borsh-derive/src/internals/serialize/enums/snapshots/generic_borsh_skip_struct_field.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/enum_ser.rs +source: borsh-derive/src/internals/serialize/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::ser::BorshSerialize for A diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__generic_borsh_skip_tuple_field.snap b/borsh-derive/src/internals/serialize/enums/snapshots/generic_borsh_skip_tuple_field.snap similarity index 93% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__generic_borsh_skip_tuple_field.snap rename to borsh-derive/src/internals/serialize/enums/snapshots/generic_borsh_skip_tuple_field.snap index 6536ec602..b667eea64 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__generic_borsh_skip_tuple_field.snap +++ b/borsh-derive/src/internals/serialize/enums/snapshots/generic_borsh_skip_tuple_field.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/enum_ser.rs +source: borsh-derive/src/internals/serialize/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::ser::BorshSerialize for A diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__generic_serialize_bound.snap b/borsh-derive/src/internals/serialize/enums/snapshots/generic_serialize_bound.snap similarity index 94% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__generic_serialize_bound.snap rename to borsh-derive/src/internals/serialize/enums/snapshots/generic_serialize_bound.snap index dc6c7bce3..3725f9b14 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__generic_serialize_bound.snap +++ b/borsh-derive/src/internals/serialize/enums/snapshots/generic_serialize_bound.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/enum_ser.rs +source: borsh-derive/src/internals/serialize/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::ser::BorshSerialize for A diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__recursive_enum.snap b/borsh-derive/src/internals/serialize/enums/snapshots/recursive_enum.snap similarity index 94% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__recursive_enum.snap rename to borsh-derive/src/internals/serialize/enums/snapshots/recursive_enum.snap index 83d79faaa..03df7be26 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__recursive_enum.snap +++ b/borsh-derive/src/internals/serialize/enums/snapshots/recursive_enum.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/enum_ser.rs +source: borsh-derive/src/internals/serialize/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::ser::BorshSerialize for A diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__simple_generics.snap b/borsh-derive/src/internals/serialize/enums/snapshots/simple_generics.snap similarity index 94% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__simple_generics.snap rename to borsh-derive/src/internals/serialize/enums/snapshots/simple_generics.snap index 8c1cb4f5c..bf9ce57e7 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__simple_generics.snap +++ b/borsh-derive/src/internals/serialize/enums/snapshots/simple_generics.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/enum_ser.rs +source: borsh-derive/src/internals/serialize/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::ser::BorshSerialize for A diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__struct_variant_field.snap b/borsh-derive/src/internals/serialize/enums/snapshots/struct_variant_field.snap similarity index 93% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__struct_variant_field.snap rename to borsh-derive/src/internals/serialize/enums/snapshots/struct_variant_field.snap index db115d2c0..e3e591a06 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__enum_ser__tests__struct_variant_field.snap +++ b/borsh-derive/src/internals/serialize/enums/snapshots/struct_variant_field.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/enum_ser.rs +source: borsh-derive/src/internals/serialize/enums/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::ser::BorshSerialize for AB { diff --git a/borsh-derive/src/internals/serialize/mod.rs b/borsh-derive/src/internals/serialize/mod.rs new file mode 100644 index 000000000..3fad21747 --- /dev/null +++ b/borsh-derive/src/internals/serialize/mod.rs @@ -0,0 +1,25 @@ +pub mod enums; +pub mod structs; +pub mod unions; + +use proc_macro2::TokenStream as TokenStream2; +use quote::{quote, ToTokens}; +use syn::{ExprPath, Ident}; + +/// function which computes derive output [proc_macro2::TokenStream] +/// of code, which serializes single field +fn field_output( + arg: &T, + cratename: &Ident, + serialize_with: Option, +) -> TokenStream2 { + if let Some(func) = serialize_with { + quote! { + #func(#arg, writer)?; + } + } else { + quote! { + #cratename::BorshSerialize::serialize(#arg, writer)?; + } + } +} diff --git a/borsh-derive-internal/src/struct_ser.rs b/borsh-derive/src/internals/serialize/structs/mod.rs similarity index 65% rename from borsh-derive-internal/src/struct_ser.rs rename to borsh-derive/src/internals/serialize/structs/mod.rs index 900e6302a..3718b2f21 100644 --- a/borsh-derive-internal/src/struct_ser.rs +++ b/borsh-derive/src/internals/serialize/structs/mod.rs @@ -1,35 +1,17 @@ use core::convert::TryFrom; use proc_macro2::{Span, TokenStream as TokenStream2}; -use quote::{quote, ToTokens}; -use syn::{Expr, ExprPath, Fields, Ident, Index, ItemStruct, Path, WhereClause}; +use quote::quote; +use syn::{Expr, Fields, Ident, Index, ItemStruct, Path, WhereClause}; -use crate::{ - attribute_helpers::{contains_skip, field, BoundType}, - generics::{compute_predicates, without_defaults, FindTyParams}, +use crate::internals::{ + attributes::{field, BoundType}, + generics, serialize, }; -/// function which computes derive output [proc_macro2::TokenStream] -/// of code, which serializes single field -pub(crate) fn field_serialization_output( - arg: &T, - cratename: &Ident, - serialize_with: Option, -) -> TokenStream2 { - if let Some(func) = serialize_with { - quote! { - #func(#arg, writer)?; - } - } else { - quote! { - #cratename::BorshSerialize::serialize(#arg, writer)?; - } - } -} - -pub fn struct_ser(input: &ItemStruct, cratename: Ident) -> syn::Result { +pub fn process(input: &ItemStruct, cratename: Ident) -> syn::Result { let name = &input.ident; - let generics = without_defaults(&input.generics); + let generics = generics::without_defaults(&input.generics); let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); let mut where_clause = where_clause.map_or_else( || WhereClause { @@ -39,12 +21,12 @@ pub fn struct_ser(input: &ItemStruct, cratename: Ident) -> syn::Result { for field in &fields.named { - let skipped = contains_skip(&field.attrs); + let skipped = field::contains_skip(&field.attrs); let parsed = field::Attributes::parse(&field.attrs, skipped)?; let needs_bounds_derive = parsed.needs_bounds_derive(BoundType::Serialize); override_predicates.extend(parsed.collect_bounds(BoundType::Serialize)); @@ -54,7 +36,7 @@ pub fn struct_ser(input: &ItemStruct, cratename: Ident) -> syn::Result syn::Result { for (field_idx, field) in fields.unnamed.iter().enumerate() { - let skipped = contains_skip(&field.attrs); + let skipped = field::contains_skip(&field.attrs); let parsed = field::Attributes::parse(&field.attrs, skipped)?; let needs_bounds_derive = parsed.needs_bounds_derive(BoundType::Serialize); override_predicates.extend(parsed.collect_bounds(BoundType::Serialize)); @@ -74,7 +56,7 @@ pub fn struct_ser(input: &ItemStruct, cratename: Ident) -> syn::Result syn::Result {} } let trait_path: Path = syn::parse2(quote! { #cratename::ser::BorshSerialize }).unwrap(); - let predicates = compute_predicates(serialize_params_visitor.process_for_bounds(), &trait_path); + let predicates = + generics::compute_predicates(serialize_params_visitor.process_for_bounds(), &trait_path); where_clause.predicates.extend(predicates); where_clause.predicates.extend(override_predicates); Ok(quote! { @@ -100,7 +83,9 @@ pub fn struct_ser(input: &ItemStruct, cratename: Ident) -> syn::Result unreachable!("expecting error here"), Err(err) => err, }; - insta::assert_debug_snapshot!(err); + local_insta_assert_debug_snapshot!(err); } } diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__bound_generics.snap b/borsh-derive/src/internals/serialize/structs/snapshots/bound_generics.snap similarity index 89% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__bound_generics.snap rename to borsh-derive/src/internals/serialize/structs/snapshots/bound_generics.snap index 907044899..8c98daa6c 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__bound_generics.snap +++ b/borsh-derive/src/internals/serialize/structs/snapshots/bound_generics.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/struct_ser.rs +source: borsh-derive/src/internals/serialize/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::ser::BorshSerialize for A diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__check_serialize_with_attr.snap b/borsh-derive/src/internals/serialize/structs/snapshots/check_serialize_with_attr.snap similarity index 89% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__check_serialize_with_attr.snap rename to borsh-derive/src/internals/serialize/structs/snapshots/check_serialize_with_attr.snap index 398bec369..0d0e6adb4 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__check_serialize_with_attr.snap +++ b/borsh-derive/src/internals/serialize/structs/snapshots/check_serialize_with_attr.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/struct_ser.rs +source: borsh-derive/src/internals/serialize/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::ser::BorshSerialize for A diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__check_serialize_with_skip_conflict.snap b/borsh-derive/src/internals/serialize/structs/snapshots/check_serialize_with_skip_conflict.snap similarity index 67% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__check_serialize_with_skip_conflict.snap rename to borsh-derive/src/internals/serialize/structs/snapshots/check_serialize_with_skip_conflict.snap index f051fc194..9eca99e53 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__check_serialize_with_skip_conflict.snap +++ b/borsh-derive/src/internals/serialize/structs/snapshots/check_serialize_with_skip_conflict.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/struct_ser.rs +source: borsh-derive/src/internals/serialize/structs/mod.rs expression: err --- Error( diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__generic_associated_type.snap b/borsh-derive/src/internals/serialize/structs/snapshots/generic_associated_type.snap similarity index 90% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__generic_associated_type.snap rename to borsh-derive/src/internals/serialize/structs/snapshots/generic_associated_type.snap index 72e0eddaa..741502cf3 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__generic_associated_type.snap +++ b/borsh-derive/src/internals/serialize/structs/snapshots/generic_associated_type.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/struct_ser.rs +source: borsh-derive/src/internals/serialize/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::ser::BorshSerialize for Parametrized diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__generic_named_fields_struct_borsh_skip.snap b/borsh-derive/src/internals/serialize/structs/snapshots/generic_named_fields_struct_borsh_skip.snap similarity index 87% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__generic_named_fields_struct_borsh_skip.snap rename to borsh-derive/src/internals/serialize/structs/snapshots/generic_named_fields_struct_borsh_skip.snap index 4567f7a98..bf041fc41 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__generic_named_fields_struct_borsh_skip.snap +++ b/borsh-derive/src/internals/serialize/structs/snapshots/generic_named_fields_struct_borsh_skip.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/struct_ser.rs +source: borsh-derive/src/internals/serialize/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::ser::BorshSerialize for G diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__generic_serialize_bound.snap b/borsh-derive/src/internals/serialize/structs/snapshots/generic_serialize_bound.snap similarity index 89% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__generic_serialize_bound.snap rename to borsh-derive/src/internals/serialize/structs/snapshots/generic_serialize_bound.snap index ad6b43046..68d8c5d88 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__generic_serialize_bound.snap +++ b/borsh-derive/src/internals/serialize/structs/snapshots/generic_serialize_bound.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/struct_ser.rs +source: borsh-derive/src/internals/serialize/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::ser::BorshSerialize for C diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__generic_tuple_struct_borsh_skip1.snap b/borsh-derive/src/internals/serialize/structs/snapshots/generic_tuple_struct_borsh_skip1.snap similarity index 87% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__generic_tuple_struct_borsh_skip1.snap rename to borsh-derive/src/internals/serialize/structs/snapshots/generic_tuple_struct_borsh_skip1.snap index b007a2999..546552e04 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__generic_tuple_struct_borsh_skip1.snap +++ b/borsh-derive/src/internals/serialize/structs/snapshots/generic_tuple_struct_borsh_skip1.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/struct_ser.rs +source: borsh-derive/src/internals/serialize/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::ser::BorshSerialize for G diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__generic_tuple_struct_borsh_skip2.snap b/borsh-derive/src/internals/serialize/structs/snapshots/generic_tuple_struct_borsh_skip2.snap similarity index 88% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__generic_tuple_struct_borsh_skip2.snap rename to borsh-derive/src/internals/serialize/structs/snapshots/generic_tuple_struct_borsh_skip2.snap index bb4c61e30..9ad7fcfe7 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__generic_tuple_struct_borsh_skip2.snap +++ b/borsh-derive/src/internals/serialize/structs/snapshots/generic_tuple_struct_borsh_skip2.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/struct_ser.rs +source: borsh-derive/src/internals/serialize/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::ser::BorshSerialize for G diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__override_generic_associated_type_wrong_derive.snap b/borsh-derive/src/internals/serialize/structs/snapshots/override_generic_associated_type_wrong_derive.snap similarity index 90% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__override_generic_associated_type_wrong_derive.snap rename to borsh-derive/src/internals/serialize/structs/snapshots/override_generic_associated_type_wrong_derive.snap index 9afa82b94..ba0d8cccb 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__override_generic_associated_type_wrong_derive.snap +++ b/borsh-derive/src/internals/serialize/structs/snapshots/override_generic_associated_type_wrong_derive.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/struct_ser.rs +source: borsh-derive/src/internals/serialize/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::ser::BorshSerialize for Parametrized diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__recursive_struct.snap b/borsh-derive/src/internals/serialize/structs/snapshots/recursive_struct.snap similarity index 87% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__recursive_struct.snap rename to borsh-derive/src/internals/serialize/structs/snapshots/recursive_struct.snap index 1a334016c..308e80c34 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__recursive_struct.snap +++ b/borsh-derive/src/internals/serialize/structs/snapshots/recursive_struct.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/struct_ser.rs +source: borsh-derive/src/internals/serialize/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::ser::BorshSerialize for CRecC { diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__simple_generic_tuple_struct.snap b/borsh-derive/src/internals/serialize/structs/snapshots/simple_generic_tuple_struct.snap similarity index 88% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__simple_generic_tuple_struct.snap rename to borsh-derive/src/internals/serialize/structs/snapshots/simple_generic_tuple_struct.snap index fe538045d..6a77431cc 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__simple_generic_tuple_struct.snap +++ b/borsh-derive/src/internals/serialize/structs/snapshots/simple_generic_tuple_struct.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/struct_ser.rs +source: borsh-derive/src/internals/serialize/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::ser::BorshSerialize for TupleA diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__simple_generics.snap b/borsh-derive/src/internals/serialize/structs/snapshots/simple_generics.snap similarity index 89% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__simple_generics.snap rename to borsh-derive/src/internals/serialize/structs/snapshots/simple_generics.snap index 4b2c16e4d..55bccb96b 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__simple_generics.snap +++ b/borsh-derive/src/internals/serialize/structs/snapshots/simple_generics.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/struct_ser.rs +source: borsh-derive/src/internals/serialize/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::ser::BorshSerialize for A diff --git a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__simple_struct.snap b/borsh-derive/src/internals/serialize/structs/snapshots/simple_struct.snap similarity index 87% rename from borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__simple_struct.snap rename to borsh-derive/src/internals/serialize/structs/snapshots/simple_struct.snap index eb7b34f9c..577d4462a 100644 --- a/borsh-derive-internal/src/snapshots/borsh_derive_internal__struct_ser__tests__simple_struct.snap +++ b/borsh-derive/src/internals/serialize/structs/snapshots/simple_struct.snap @@ -1,5 +1,5 @@ --- -source: borsh-derive-internal/src/struct_ser.rs +source: borsh-derive/src/internals/serialize/structs/mod.rs expression: pretty_print_syn_str(&actual).unwrap() --- impl borsh::ser::BorshSerialize for A { diff --git a/borsh-derive-internal/src/union_ser.rs b/borsh-derive/src/internals/serialize/unions/mod.rs similarity index 53% rename from borsh-derive-internal/src/union_ser.rs rename to borsh-derive/src/internals/serialize/unions/mod.rs index a86a6dc39..cec91db74 100644 --- a/borsh-derive-internal/src/union_ser.rs +++ b/borsh-derive/src/internals/serialize/unions/mod.rs @@ -1,6 +1,6 @@ use proc_macro2::TokenStream as TokenStream2; use syn::{Ident, ItemUnion}; -pub fn union_ser(_input: &ItemUnion, _cratename: Ident) -> syn::Result { +pub fn process(_input: &ItemUnion, _cratename: Ident) -> syn::Result { unimplemented!() } diff --git a/borsh-derive/src/internals/test_helpers.rs b/borsh-derive/src/internals/test_helpers.rs new file mode 100644 index 000000000..b8efa18f2 --- /dev/null +++ b/borsh-derive/src/internals/test_helpers.rs @@ -0,0 +1,52 @@ +use proc_macro2::TokenStream; +use quote::{quote, ToTokens}; +use std::fmt::Write; + +pub fn pretty_print_syn_str(input: &TokenStream) -> syn::Result { + let input = format!("{}", quote!(#input)); + let syn_file = syn::parse_str::(&input)?; + + Ok(prettyplease::unparse(&syn_file)) +} + +pub fn debug_print_vec_of_tokenizable(optional: Option>) -> String { + let mut s = String::new(); + if let Some(vec) = optional { + for element in vec { + writeln!(&mut s, "{}", element.to_token_stream()).unwrap(); + } + } else { + write!(&mut s, "None").unwrap(); + } + s +} + +pub fn debug_print_tokenizable(optional: Option) -> String { + let mut s = String::new(); + if let Some(type_) = optional { + writeln!(&mut s, "{}", type_.to_token_stream()).unwrap(); + } else { + write!(&mut s, "None").unwrap(); + } + s +} + +macro_rules! local_insta_assert_debug_snapshot { + ($value:expr) => {{ + + insta::with_settings!({prepend_module_to_snapshot => false}, { + insta::assert_debug_snapshot!($value); + }); + }}; +} + +macro_rules! local_insta_assert_snapshot { + ($value:expr) => {{ + + insta::with_settings!({prepend_module_to_snapshot => false}, { + insta::assert_snapshot!($value); + }); + }}; +} + +pub(crate) use {local_insta_assert_debug_snapshot, local_insta_assert_snapshot}; diff --git a/borsh-derive/src/lib.rs b/borsh-derive/src/lib.rs index 4157446af..a719b00a0 100644 --- a/borsh-derive/src/lib.rs +++ b/borsh-derive/src/lib.rs @@ -1,3 +1,9 @@ +#![recursion_limit = "128"] +#![cfg_attr( + feature = "force_exhaustive_checks", + feature(non_exhaustive_omitted_patterns_lint) +)] + extern crate proc_macro; use proc_macro::TokenStream; use proc_macro2::Span; @@ -5,9 +11,14 @@ use proc_macro_crate::crate_name; use proc_macro_crate::FoundCrate; use syn::{parse_macro_input, DeriveInput, Ident, ItemEnum, ItemStruct, ItemUnion}; -use borsh_derive_internal::*; +/// by convention, local to borsh-derive crate, imports from proc_macro (1) are not allowed in `internals` module or in any of its submodules. +mod internals; + +use crate::internals::attributes::item::check_item_attributes; + #[cfg(feature = "schema")] -use borsh_schema_derive_internal::*; +use internals::schema; +use internals::{deserialize, serialize}; /** # derive proc-macro for `borsh::ser::BorshSerialize` trait @@ -232,11 +243,11 @@ pub fn borsh_serialize(input: TokenStream) -> TokenStream { } let res = if let Ok(input) = syn::parse::(input.clone()) { - struct_ser(&input, cratename) + serialize::structs::process(&input, cratename) } else if let Ok(input) = syn::parse::(input.clone()) { - enum_ser(&input, cratename) + serialize::enums::process(&input, cratename) } else if let Ok(input) = syn::parse::(input) { - union_ser(&input, cratename) + serialize::unions::process(&input, cratename) } else { // Derive macros can only be defined on structs, enums, and unions. unreachable!() @@ -526,11 +537,11 @@ pub fn borsh_deserialize(input: TokenStream) -> TokenStream { } let res = if let Ok(input) = syn::parse::(input.clone()) { - struct_de(&input, cratename) + deserialize::structs::process(&input, cratename) } else if let Ok(input) = syn::parse::(input.clone()) { - enum_de(&input, cratename) + deserialize::enums::process(&input, cratename) } else if let Ok(input) = syn::parse::(input) { - union_de(&input, cratename) + deserialize::unions::process(&input, cratename) } else { // Derive macros can only be defined on structs, enums, and unions. unreachable!() @@ -594,7 +605,7 @@ struct A { ###### syntax -Attribute takes literal string value, which is a comma-separated list of [ParameterOverride](borsh_derive_internal::attribute_helpers::field::schema::ParameterOverride)-s, which may be empty. +Attribute takes literal string value, which is a comma-separated list of `ParameterOverride`-s, which may be empty. ###### usage It may be used in order to: @@ -603,7 +614,7 @@ It may be used in order to: declaration parameters automatically. 2. remove parameters, which do not take part in serialization/deserialization, from bounded ones and from declaration parameters. -[ParameterOverride](borsh_derive_internal::attribute_helpers::field::schema::ParameterOverride) describes an entry like `order_param => override_type`, +`ParameterOverride` describes an entry like `order_param => override_type`, e.g. `K => ::Associated`. @@ -741,9 +752,9 @@ pub fn borsh_schema(input: TokenStream) -> TokenStream { let cratename = Ident::new(name, Span::call_site()); let res = if let Ok(input) = syn::parse::(input.clone()) { - process_struct(&input, cratename) + schema::structs::process(&input, cratename) } else if let Ok(input) = syn::parse::(input.clone()) { - process_enum(&input, cratename) + schema::enums::process(&input, cratename) } else if syn::parse::(input).is_ok() { Err(syn::Error::new( Span::call_site(), diff --git a/borsh-schema-derive-internal/Cargo.toml b/borsh-schema-derive-internal/Cargo.toml deleted file mode 100644 index 7e5cb4b28..000000000 --- a/borsh-schema-derive-internal/Cargo.toml +++ /dev/null @@ -1,29 +0,0 @@ -[package] -name = "borsh-schema-derive-internal" -version.workspace = true -rust-version.workspace = true -authors = ["Near Inc "] -edition = "2018" -license = "Apache-2.0" -categories = ["encoding", "network-programming"] -repository = "https://github.com/nearprotocol/borsh" -homepage = "https://borsh.io" -description = """ -Schema Generator for Borsh -""" - -[dependencies] -proc-macro2 = "1" -syn = { version = "2", features = ["full", "fold"] } -quote = "1" -syn_derive = "0.1.6" -once_cell = "1.18.0" - -[dev-dependencies] -syn = { version = "2", features = ["full", "fold", "parsing"] } -prettyplease = "0.2.9" -insta = "1.29.0" - -[features] -default = [] -force_exhaustive_checks = [] diff --git a/borsh-schema-derive-internal/README.md b/borsh-schema-derive-internal/README.md deleted file mode 120000 index 32d46ee88..000000000 --- a/borsh-schema-derive-internal/README.md +++ /dev/null @@ -1 +0,0 @@ -../README.md \ No newline at end of file diff --git a/borsh-schema-derive-internal/src/attribute_helpers/field.rs b/borsh-schema-derive-internal/src/attribute_helpers/field.rs deleted file mode 100644 index 23a7b1a5c..000000000 --- a/borsh-schema-derive-internal/src/attribute_helpers/field.rs +++ /dev/null @@ -1,190 +0,0 @@ -#![allow(unused)] -// TODO: remove unused when unsplit is done -use std::collections::BTreeMap; - -use once_cell::sync::Lazy; -use syn::{meta::ParseNestedMeta, Attribute, ExprPath, WherePredicate}; - -use self::{bounds::BOUNDS_FIELD_PARSE_MAP, schema::SCHEMA_FIELD_PARSE_MAP}; - -use super::{ - parsing::{attr_get_by_symbol_keys, meta_get_by_symbol_keys, parse_lit_into}, - BoundType, Symbol, BORSH, BOUND, DESERIALIZE_WITH, PARAMS, SCHEMA, SERIALIZE_WITH, SKIP, - WITH_FUNCS, -}; - -pub mod bounds; -pub mod schema; - -enum Variants { - Schema(schema::Attributes), - Bounds(bounds::Bounds), - SerializeWith(syn::ExprPath), - DeserializeWith(syn::ExprPath), -} - -type ParseFn = dyn Fn(Symbol, Symbol, &ParseNestedMeta) -> syn::Result + Send + Sync; - -static BORSH_FIELD_PARSE_MAP: Lazy>> = Lazy::new(|| { - let mut m = BTreeMap::new(); - // assigning closure `let f = |args| {...};` and boxing closure `let f: Box = Box::new(f);` - // on 2 separate lines doesn't work - let f_bounds: Box = Box::new(|_attr_name, _meta_item_name, meta| { - let map_result = meta_get_by_symbol_keys(BOUND, meta, &BOUNDS_FIELD_PARSE_MAP)?; - let bounds_attributes: bounds::Bounds = map_result.into(); - Ok(Variants::Bounds(bounds_attributes)) - }); - - let f_schema: Box = Box::new(|_attr_name, _meta_item_name, meta| { - let map_result = meta_get_by_symbol_keys(SCHEMA, meta, &SCHEMA_FIELD_PARSE_MAP)?; - let schema_attributes: schema::Attributes = map_result.into(); - Ok(Variants::Schema(schema_attributes)) - }); - - let f_serialize_with: Box = Box::new(|attr_name, meta_item_name, meta| { - parse_lit_into::(attr_name, meta_item_name, meta) - .map(Variants::SerializeWith) - }); - - let f_deserialize_with: Box = Box::new(|attr_name, meta_item_name, meta| { - parse_lit_into::(attr_name, meta_item_name, meta) - .map(Variants::DeserializeWith) - }); - - m.insert(BOUND, f_bounds); - m.insert(SCHEMA, f_schema); - m.insert(SERIALIZE_WITH, f_serialize_with); - m.insert(DESERIALIZE_WITH, f_deserialize_with); - m -}); - -#[derive(Default)] -pub(crate) struct Attributes { - pub bounds: Option, - pub schema: Option, - pub serialize_with: Option, - pub deserialize_with: Option, -} - -impl From> for Attributes { - fn from(mut map: BTreeMap) -> Self { - let bounds = map.remove(&BOUND); - let schema = map.remove(&SCHEMA); - let serialize_with = map.remove(&SERIALIZE_WITH); - let deserialize_with = map.remove(&DESERIALIZE_WITH); - let bounds = bounds.map(|variant| match variant { - Variants::Bounds(bounds) => bounds, - _ => unreachable!("only one enum variant is expected to correspond to given map key"), - }); - let schema = schema.map(|variant| match variant { - Variants::Schema(schema) => schema, - _ => unreachable!("only one enum variant is expected to correspond to given map key"), - }); - - let serialize_with = serialize_with.map(|variant| match variant { - Variants::SerializeWith(serialize_with) => serialize_with, - _ => unreachable!("only one enum variant is expected to correspond to given map key"), - }); - - let deserialize_with = deserialize_with.map(|variant| match variant { - Variants::DeserializeWith(deserialize_with) => deserialize_with, - _ => unreachable!("only one enum variant is expected to correspond to given map key"), - }); - Self { - bounds, - schema, - serialize_with, - deserialize_with, - } - } -} -impl Attributes { - fn check(&self, skipped: bool, attr: &Attribute) -> Result<(), syn::Error> { - if skipped && (self.serialize_with.is_some() || self.deserialize_with.is_some()) { - return Err(syn::Error::new_spanned( - attr, - format!( - "`{}` cannot be used at the same time as `{}` or `{}`", - SKIP.0, SERIALIZE_WITH.0, DESERIALIZE_WITH.0 - ), - )); - } - if let Some(ref schema) = self.schema { - if skipped && schema.params.is_some() { - return Err(syn::Error::new_spanned( - attr, - format!( - "`{}` cannot be used at the same time as `{}({})`", - SKIP.0, SCHEMA.0, PARAMS.1 - ), - )); - } - - if skipped && schema.with_funcs.is_some() { - return Err(syn::Error::new_spanned( - attr, - format!( - "`{}` cannot be used at the same time as `{}({})`", - SKIP.0, SCHEMA.0, WITH_FUNCS.1 - ), - )); - } - } - Ok(()) - } - pub(crate) fn parse(attrs: &[Attribute], skipped: bool) -> Result { - let attr = attrs.iter().find(|attr| attr.path() == BORSH); - - let result: Self = if let Some(attr) = attr { - let result: Self = attr_get_by_symbol_keys(BORSH, attr, &BORSH_FIELD_PARSE_MAP)?.into(); - result.check(skipped, attr)?; - result - } else { - BTreeMap::new().into() - }; - - Ok(result) - } - pub(crate) fn needs_bounds_derive(&self, ty: BoundType) -> bool { - let predicates = self.get_bounds(ty); - predicates.is_none() - } - - pub(crate) fn needs_schema_params_derive(&self) -> bool { - if let Some(ref schema) = self.schema { - if schema.params.is_some() { - return false; - } - } - true - } - pub(crate) fn schema_declaration(&self) -> Option { - self.schema.as_ref().and_then(|schema| { - schema - .with_funcs - .as_ref() - .and_then(|with_funcs| with_funcs.declaration.clone()) - }) - } - - pub(crate) fn schema_definitions(&self) -> Option { - self.schema.as_ref().and_then(|schema| { - schema - .with_funcs - .as_ref() - .and_then(|with_funcs| with_funcs.definitions.clone()) - }) - } - - fn get_bounds(&self, ty: BoundType) -> Option> { - let bounds = self.bounds.as_ref(); - bounds.and_then(|bounds| match ty { - BoundType::Serialize => bounds.serialize.clone(), - BoundType::Deserialize => bounds.deserialize.clone(), - }) - } - pub(crate) fn collect_bounds(&self, ty: BoundType) -> Vec { - let predicates = self.get_bounds(ty); - predicates.unwrap_or(vec![]) - } -} diff --git a/borsh-schema-derive-internal/src/attribute_helpers/field/schema.rs b/borsh-schema-derive-internal/src/attribute_helpers/field/schema.rs deleted file mode 100644 index d00620269..000000000 --- a/borsh-schema-derive-internal/src/attribute_helpers/field/schema.rs +++ /dev/null @@ -1,83 +0,0 @@ -use std::collections::BTreeMap; - -use crate::attribute_helpers::{ - parsing::{meta_get_by_symbol_keys, parse_lit_into_vec}, - Symbol, DECLARATION, DEFINITIONS, PARAMS, WITH_FUNCS, -}; -use once_cell::sync::Lazy; -use syn::{meta::ParseNestedMeta, Ident, Token, Type}; - -use self::with_funcs::{WithFuncs, WITH_FUNCS_FIELD_PARSE_MAP}; - -pub mod with_funcs; - -pub(crate) enum Variants { - Params(Vec), - WithFuncs(WithFuncs), -} - -type ParseFn = dyn Fn(Symbol, Symbol, &ParseNestedMeta) -> syn::Result + Send + Sync; - -pub(crate) static SCHEMA_FIELD_PARSE_MAP: Lazy>> = Lazy::new(|| { - let mut m = BTreeMap::new(); - // assigning closure `let f = |args| {...};` and boxing closure `let f: Box = Box::new(f);` - // on 2 separate lines doesn't work - let f_params: Box = Box::new(|attr_name, meta_item_name, meta| { - parse_lit_into_vec::(attr_name, meta_item_name, meta) - .map(Variants::Params) - }); - - let f_with_funcs: Box = Box::new(|_attr_name, _meta_item_name, meta| { - let map_result = meta_get_by_symbol_keys(WITH_FUNCS, meta, &WITH_FUNCS_FIELD_PARSE_MAP)?; - let with_funcs: WithFuncs = map_result.into(); - if (with_funcs.declaration.is_some() && with_funcs.definitions.is_none()) - || (with_funcs.declaration.is_none() && with_funcs.definitions.is_some()) - { - return Err(syn::Error::new_spanned( - &meta.path, - format!( - "both `{}` and `{}` have to be specified at the same time", - DECLARATION.1, DEFINITIONS.1, - ), - )); - } - Ok(Variants::WithFuncs(with_funcs)) - }); - m.insert(PARAMS, f_params); - m.insert(WITH_FUNCS, f_with_funcs); - m -}); - -/** -Struct describes an entry like `order_param => override_type`, e.g. `K => ::Associated` -*/ -#[derive(Clone, syn_derive::Parse, syn_derive::ToTokens)] -pub struct ParameterOverride { - pub order_param: Ident, - arrow_token: Token![=>], - pub override_type: Type, -} - -#[allow(unused)] -#[derive(Default)] -pub(crate) struct Attributes { - pub params: Option>, - pub with_funcs: Option, -} - -impl From> for Attributes { - fn from(mut map: BTreeMap) -> Self { - let params = map.remove(&PARAMS); - let params = params.map(|variant| match variant { - Variants::Params(params) => params, - _ => unreachable!("only one enum variant is expected to correspond to given map key"), - }); - - let with_funcs = map.remove(&WITH_FUNCS); - let with_funcs = with_funcs.map(|variant| match variant { - Variants::WithFuncs(with_funcs) => with_funcs, - _ => unreachable!("only one enum variant is expected to correspond to given map key"), - }); - Self { params, with_funcs } - } -} diff --git a/borsh-schema-derive-internal/src/attribute_helpers/mod.rs b/borsh-schema-derive-internal/src/attribute_helpers/mod.rs deleted file mode 100644 index 8d9659fc1..000000000 --- a/borsh-schema-derive-internal/src/attribute_helpers/mod.rs +++ /dev/null @@ -1,160 +0,0 @@ -#![allow(unused)] -// TODO: remove unused when unsplit is done -use proc_macro2::TokenStream; -use quote::ToTokens; -use syn::{spanned::Spanned, Attribute, DeriveInput, Expr, ItemEnum, Path}; - -pub mod field; -pub mod parsing; - -/// first field is attr name -/// second field is its expected value format representation for error printing -#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord)] -pub struct Symbol(pub &'static str, pub &'static str); - -/// borsh - top level prefix in nested meta attribute -pub const BORSH: Symbol = Symbol("borsh", "borsh(...)"); -/// bound - sub-borsh nested meta, field-level only, `BorshSerialize` and `BorshDeserialize` contexts -pub const BOUND: Symbol = Symbol("bound", "bound(...)"); -// use_discriminant - sub-borsh nested meta, item-level only, enums only, `BorshSerialize` and `BorshDeserialize` contexts -pub const USE_DISCRIMINANT: &str = "use_discriminant"; -/// serialize - sub-bound nested meta attribute -pub const SERIALIZE: Symbol = Symbol("serialize", "serialize = ..."); -/// deserialize - sub-bound nested meta attribute -pub const DESERIALIZE: Symbol = Symbol("deserialize", "deserialize = ..."); -/// borsh_skip - field-level only attribute, `BorshSerialize`, `BorshDeserialize`, `BorshSchema` contexts -pub const SKIP: Symbol = Symbol("borsh_skip", "borsh_skip"); -/// borsh_init - item-level only attribute `BorshDeserialize` context -pub const INIT: Symbol = Symbol("borsh_init", "borsh_init(...)"); -/// schema - sub-borsh nested meta, `BorshSchema` context -pub const SCHEMA: Symbol = Symbol("schema", "schema(...)"); -/// params - sub-schema nested meta, field-level only attribute -pub const PARAMS: Symbol = Symbol("params", "params = ..."); -/// serialize_with - sub-borsh nested meta, field-level only, `BorshSerialize` context -pub const SERIALIZE_WITH: Symbol = Symbol("serialize_with", "serialize_with = ..."); -/// deserialize_with - sub-borsh nested meta, field-level only, `BorshDeserialize` context -pub const DESERIALIZE_WITH: Symbol = Symbol("deserialize_with", "deserialize_with = ..."); -/// with_funcs - sub-schema nested meta, field-level only attribute -pub const WITH_FUNCS: Symbol = Symbol("with_funcs", "with_funcs(...)"); -/// declaration - sub-with_funcs nested meta, field-level only attribute -pub const DECLARATION: Symbol = Symbol("declaration", "declaration = ..."); -/// definitions - sub-with_funcs nested meta, field-level only attribute -pub const DEFINITIONS: Symbol = Symbol("definitions", "definitions = ..."); - -#[derive(Clone, Copy)] -pub(crate) enum BoundType { - Serialize, - Deserialize, -} -impl PartialEq for Path { - fn eq(&self, word: &Symbol) -> bool { - self.is_ident(word.0) - } -} - -impl<'a> PartialEq for &'a Path { - fn eq(&self, word: &Symbol) -> bool { - self.is_ident(word.0) - } -} - -pub(crate) fn contains_skip(attrs: &[Attribute]) -> bool { - attrs.iter().any(|attr| attr.path() == SKIP) -} - -pub fn check_item_attributes(derive_input: &DeriveInput) -> Result<(), TokenStream> { - for attr in &derive_input.attrs { - if attr.path().is_ident(SKIP.0) { - return Err(syn::Error::new( - derive_input.ident.span(), - "`borsh_skip` is not allowed as derive input attribute", - ) - .to_compile_error()); - } - if attr.path().is_ident(BORSH.0) { - attr.parse_nested_meta(|meta| { - if !meta.path.is_ident(USE_DISCRIMINANT) { - return Err(syn::Error::new( - meta.path.span(), - "`use_discriminant` is the only supported attribute for `borsh`", - )); - } - if meta.path.is_ident(USE_DISCRIMINANT) { - let _expr: Expr = meta.value()?.parse()?; - if let syn::Data::Struct(ref _data) = derive_input.data { - return Err(syn::Error::new( - derive_input.ident.span(), - "borsh(use_discriminant=) does not support structs", - )); - } - } - - Ok(()) - }) - .map_err(|err| err.to_compile_error())?; - } - } - Ok(()) -} - -pub(crate) fn contains_use_discriminant(input: &ItemEnum) -> Result { - if input.variants.len() > 256 { - return Err(syn::Error::new( - input.span(), - "up to 256 enum variants are supported", - )); - } - - let attrs = &input.attrs; - let mut use_discriminant = None; - for attr in attrs { - if attr.path().is_ident(BORSH.0) { - attr.parse_nested_meta(|meta| { - if meta.path.is_ident(USE_DISCRIMINANT) { - let value_expr: Expr = meta.value()?.parse()?; - let value = value_expr.to_token_stream().to_string(); - match value.as_str() { - "true" => { - use_discriminant = Some(true); - } - "false" => use_discriminant = Some(false), - _ => { - return Err(syn::Error::new( - value_expr.span(), - "`use_discriminant` accepts only `true` or `false`", - )); - } - }; - } - - Ok(()) - })?; - } - } - let has_explicit_discriminants = input - .variants - .iter() - .any(|variant| variant.discriminant.is_some()); - if has_explicit_discriminants && use_discriminant.is_none() { - return Err(syn::Error::new( - input.ident.span(), - "You have to specify `#[borsh(use_discriminant=true)]` or `#[borsh(use_discriminant=false)]` for all enums with explicit discriminant", - )); - } - Ok(use_discriminant.unwrap_or(false)) -} - -pub(crate) fn contains_initialize_with(attrs: &[Attribute]) -> Option { - for attr in attrs.iter() { - if attr.path() == INIT { - let mut res = None; - let _ = attr.parse_nested_meta(|meta| { - res = Some(meta.path); - Ok(()) - }); - return res; - } - } - - None -} diff --git a/borsh-schema-derive-internal/src/attribute_helpers/parsing.rs b/borsh-schema-derive-internal/src/attribute_helpers/parsing.rs deleted file mode 100644 index 7ebf8e778..000000000 --- a/borsh-schema-derive-internal/src/attribute_helpers/parsing.rs +++ /dev/null @@ -1,123 +0,0 @@ -use std::{collections::BTreeMap, iter::FromIterator}; - -use syn::{ - meta::ParseNestedMeta, punctuated::Punctuated, token::Paren, Attribute, Expr, Lit, LitStr, - Token, -}; - -use super::Symbol; - -fn get_lit_str2( - attr_name: Symbol, - meta_item_name: Symbol, - meta: &ParseNestedMeta, -) -> syn::Result { - let expr: Expr = meta.value()?.parse()?; - let mut value = &expr; - while let Expr::Group(e) = value { - value = &e.expr; - } - if let Expr::Lit(syn::ExprLit { - lit: Lit::Str(lit), .. - }) = value - { - Ok(lit.clone()) - } else { - Err(syn::Error::new_spanned( - expr, - format!( - "expected borsh {} attribute to be a string: `{} = \"...\"`", - attr_name.0, meta_item_name.0 - ), - )) - } -} - -pub(super) fn parse_lit_into( - attr_name: Symbol, - meta_item_name: Symbol, - meta: &ParseNestedMeta, -) -> syn::Result { - let string = get_lit_str2(attr_name, meta_item_name, meta)?; - - match string.parse() { - Ok(expr) => Ok(expr), - Err(err) => Err(syn::Error::new_spanned(string, err)), - } -} - -pub(super) fn parse_lit_into_vec( - attr_name: Symbol, - meta_item_name: Symbol, - meta: &ParseNestedMeta, -) -> syn::Result> { - let string = get_lit_str2(attr_name, meta_item_name, meta)?; - - match string.parse_with(Punctuated::::parse_terminated) { - Ok(elements) => Ok(Vec::from_iter(elements)), - Err(err) => Err(syn::Error::new_spanned(string, err)), - } -} - -fn get_nested_meta_logic( - attr_name: Symbol, - meta: ParseNestedMeta, - map: &BTreeMap, - result: &mut BTreeMap, -) -> syn::Result<()> -where - F: Fn(Symbol, Symbol, &ParseNestedMeta) -> syn::Result, -{ - let mut match_ = false; - for (symbol_key, func) in map.iter() { - if meta.path == *symbol_key { - let v = func(attr_name, *symbol_key, &meta)?; - result.insert(*symbol_key, v); - match_ = true; - } - } - if !match_ { - let keys_strs = map.keys().map(|symbol| symbol.1).collect::>(); - let keys_strs = keys_strs.join(", "); - return Err(meta.error(format_args!( - "malformed {0} attribute, expected `{0}({1})`", - attr_name.0, keys_strs - ))); - } - Ok(()) -} - -pub(super) fn meta_get_by_symbol_keys( - attr_name: Symbol, - meta: &ParseNestedMeta, - map: &BTreeMap, -) -> syn::Result> -where - F: Fn(Symbol, Symbol, &ParseNestedMeta) -> syn::Result, -{ - let mut result = BTreeMap::new(); - - let lookahead = meta.input.lookahead1(); - if lookahead.peek(Paren) { - meta.parse_nested_meta(|meta| get_nested_meta_logic(attr_name, meta, map, &mut result))?; - } else { - return Err(lookahead.error()); - } - - Ok(result) -} - -pub(super) fn attr_get_by_symbol_keys( - attr_name: Symbol, - attr: &Attribute, - map: &BTreeMap, -) -> syn::Result> -where - F: Fn(Symbol, Symbol, &ParseNestedMeta) -> syn::Result, -{ - let mut result = BTreeMap::new(); - - attr.parse_nested_meta(|meta| get_nested_meta_logic(attr_name, meta, map, &mut result))?; - - Ok(result) -} diff --git a/borsh-schema-derive-internal/src/lib.rs b/borsh-schema-derive-internal/src/lib.rs deleted file mode 100644 index a004dfcd5..000000000 --- a/borsh-schema-derive-internal/src/lib.rs +++ /dev/null @@ -1,17 +0,0 @@ -#![recursion_limit = "128"] -#![cfg_attr( - feature = "force_exhaustive_checks", - feature(non_exhaustive_omitted_patterns_lint) -)] - -mod attribute_helpers; -mod generics; -mod schema_helpers; - -mod enum_schema; -mod struct_schema; -pub use enum_schema::process_enum; -pub use struct_schema::process_struct; - -#[cfg(test)] -pub mod test_helpers; diff --git a/borsh-schema-derive-internal/src/schema_helpers.rs b/borsh-schema-derive-internal/src/schema_helpers.rs deleted file mode 100644 index 1760f6e7a..000000000 --- a/borsh-schema-derive-internal/src/schema_helpers.rs +++ /dev/null @@ -1,85 +0,0 @@ -use std::collections::HashSet; - -use proc_macro2::TokenStream as TokenStream2; -use quote::quote; -use syn::{ - punctuated::Punctuated, token::Comma, Attribute, GenericParam, Generics, Ident, Type, - WherePredicate, -}; - -use crate::{ - attribute_helpers::{BORSH, SKIP}, - generics::type_contains_some_param, -}; - -pub fn filter_field_attrs( - attrs: impl Iterator, -) -> impl Iterator { - attrs.filter(|attr| attr.path() == SKIP || attr.path() == BORSH) -} - -pub fn declaration( - ident_str: &str, - cratename: Ident, - params_for_bounds: Vec, -) -> TokenStream2 { - // Generate function that returns the name of the type. - let mut declaration_params = vec![]; - for type_param in params_for_bounds { - declaration_params.push(quote! { - <#type_param>::declaration() - }); - } - if declaration_params.is_empty() { - quote! { - #ident_str.to_string() - } - } else { - quote! { - let params = #cratename::__private::maybestd::vec![#(#declaration_params),*]; - format!(r#"{}<{}>"#, #ident_str, params.join(", ")) - } - } -} - -pub fn filter_used_params( - generics: &Generics, - not_skipped_type_params: HashSet, -) -> Generics { - let new_params = generics - .params - .clone() - .into_iter() - .filter(|param| match param { - GenericParam::Lifetime(..) | GenericParam::Const(..) => true, - GenericParam::Type(ty_param) => not_skipped_type_params.contains(&ty_param.ident), - }) - .collect(); - - let mut where_clause = generics.where_clause.clone(); - where_clause = where_clause.map(|mut clause| { - let new_predicates: Punctuated = clause - .predicates - .iter() - .filter(|predicate| match predicate { - WherePredicate::Lifetime(..) => true, - WherePredicate::Type(predicate_type) => { - type_contains_some_param(&predicate_type.bounded_ty, ¬_skipped_type_params) - } - #[cfg_attr( - feature = "force_exhaustive_checks", - deny(non_exhaustive_omitted_patterns) - )] - _ => true, - }) - .cloned() - .collect(); - clause.predicates = new_predicates; - clause - }); - Generics { - params: new_params, - where_clause, - ..generics.clone() - } -} diff --git a/borsh-schema-derive-internal/src/test_helpers.rs b/borsh-schema-derive-internal/src/test_helpers.rs deleted file mode 100644 index 6c4d17a3d..000000000 --- a/borsh-schema-derive-internal/src/test_helpers.rs +++ /dev/null @@ -1,9 +0,0 @@ -use proc_macro2::TokenStream; -use quote::quote; - -pub fn pretty_print_syn_str(input: &TokenStream) -> syn::Result { - let input = format!("{}", quote!(#input)); - let syn_file = syn::parse_str::(&input)?; - - Ok(prettyplease::unparse(&syn_file)) -}