Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion max-encoded-len/derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@ fn generate_crate_access_2018(def_crate: &str) -> Result<syn::Ident, Error> {
/// Derive `MaxEncodedLen`.
#[proc_macro_derive(MaxEncodedLen, attributes(max_encoded_len_crate))]
pub fn derive_max_encoded_len(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
parse_and_generate_mel(input, false)
}

/// Derive `MaxEncodedLen` but do not bound any generics.
#[proc_macro_derive(MaxEncodedLenNoBound, attributes(max_encoded_len_crate))]
pub fn derive_max_encoded_len_no_bound(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
parse_and_generate_mel(input, true)
}

fn parse_and_generate_mel(input: proc_macro::TokenStream, no_bound: bool) -> proc_macro::TokenStream {
let input: DeriveInput = match syn::parse(input) {
Ok(input) => input,
Err(e) => return e.to_compile_error().into(),
Expand All @@ -53,7 +63,11 @@ pub fn derive_max_encoded_len(input: proc_macro::TokenStream) -> proc_macro::Tok
};

let name = &input.ident;
let generics = add_trait_bounds(input.generics, mel_trait.clone());
let generics = if no_bound {
input.generics
} else {
add_trait_bounds(input.generics, mel_trait.clone())
};
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();

let data_expr = data_length_expr(&input.data);
Expand Down
5 changes: 5 additions & 0 deletions max-encoded-len/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ use primitive_types::{H160, H256, H512};
#[cfg(feature = "derive")]
pub use max_encoded_len_derive::MaxEncodedLen;

/// Same as `MaxEncodedLen`, but without bounding the generics on the derived type with
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Same as `MaxEncodedLen`, but without bounding the generics on the derived type with
/// Same as [`MaxEncodedLen`](macro@MaxEncodedLen), but without bounding the generics on the derived type with

/// `MaxEncodedLen`.
#[cfg(feature = "derive")]
pub use max_encoded_len_derive::MaxEncodedLenNoBound;

/// Items implementing `MaxEncodedLen` have a statically known maximum encoded size.
///
/// Some containers, such as `BoundedVec`, have enforced size limits and this trait
Expand Down
13 changes: 12 additions & 1 deletion max-encoded-len/tests/max_encoded_len.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@

#![cfg(feature = "derive")]

use max_encoded_len::MaxEncodedLen;
use max_encoded_len::{MaxEncodedLen, MaxEncodedLenNoBound};
use std::marker::PhantomData;
use codec::{Compact, Encode};

// These structs won't even compile if the macro isn't working right.
Expand Down Expand Up @@ -76,6 +77,16 @@ fn two_generics_max_length() {
);
}

#[derive(Encode, MaxEncodedLenNoBound)]
struct NoBoundGeneric<T> {
one: PhantomData<T>,
}

#[test]
fn no_bound_generic() {
assert_eq!(NoBoundGeneric::<u8>::max_encoded_len(), 0);
}

#[derive(Encode, MaxEncodedLen)]
struct UnitStruct;

Expand Down