Gen6_Public_Blockchain/pallets/identity/src/identity_macros.rs

294 lines
9.3 KiB
Rust

/// Macro for generating pub enum IdentityField
/// E.g.
///
///
/// The fields that we use to identify the owner of an account with. Each corresponds to a field
/// in the `IdentityInfo` struct.
/// #[bitflags]
/// #[repr(u64)]
/// #[derive(Clone, Copy, PartialEq, Eq, RuntimeDebug)]
/// pub enum IdentityField {
/// Display,
/// FirstName,
/// LastName,
/// Email,
/// Address,
/// TelephoneNumber,
/// Bio,
/// }
#[macro_export]
macro_rules! generate_identity_field_enum {
($($variant:ident),* $(,)?) => {
#[bitflags]
#[repr(u64)]
#[derive(Clone, Copy, PartialEq, Eq, RuntimeDebug)]
pub enum IdentityField {
$(
$variant,
)*
}
}
}
/// Macro for generating impl TypeInfo for IdentityField
/// E.g.
///
/// use scale_info::{build::Variants, Path, Type, TypeInfo};
///
/// impl TypeInfo for IdentityField {
/// type Identity = Self;
///
/// fn type_info() -> scale_info::Type {
/// Type::builder()
/// .path(Path::new("IdentityField", module_path!()))
/// .variant(
/// Variants::new()
/// .variant("Display", |v| v.index(0))
/// .variant("FirstName", |v| v.index(1))
/// .variant("LastName", |v| v.index(2))
/// .variant("Email", |v| v.index(3))
/// .variant("Address", |v| v.index(4))
/// .variant("TelephoneNumber", |v| v.index(5))
/// .variant("Bio", |v| v.index(6)),
/// )
/// }
/// }
#[macro_export]
macro_rules! generate_type_info {
($name:ident, $variants:expr) => {
impl TypeInfo for $name {
type Identity = Self;
fn type_info() -> scale_info::Type {
scale_info::Type::builder()
.path(scale_info::Path::new(stringify!($name), module_path!()))
.type_params(vec![])
.variant($variants.iter().enumerate().fold(
scale_info::build::Variants::new(),
|variants, (index, variant)| {
variants.variant(*variant, |v| v.index(index as u8))
},
))
}
}
};
}
/// Macro to generate the `impl` block for `IdentityInformationProvider` for `IdentityInfo`.
///
/// Parameters:
/// - `$type_name`: The name of the struct (e.g., `IdentityInfo`).
/// - `$field_limit`: The generic parameter for field limit (e.g., `FieldLimit`).
/// - `$fields`: A list of tuples containing field names and their associated data lengths.
///
/// Usage:
/// ```rust
/// generate_identity_information_provider_impl!(
/// IdentityInfo,
/// FieldLimit,
/// (display, DEFAULT_DATA_MAX_LENGTH),
/// (first_name, DEFAULT_DATA_MAX_LENGTH),
/// (last_name, DEFAULT_DATA_MAX_LENGTH),
/// (email, DEFAULT_DATA_MAX_LENGTH),
/// (address, DEFAULT_DATA_MAX_LENGTH),
/// (telephone_number, DEFAULT_DATA_MAX_LENGTH),
/// (bio, BIO_DATA_MAX_LENGTH)
/// );
/// ```
/// E.g.
///
///
/// impl<FieldLimit: Get<u32> + 'static> IdentityInformationProvider for IdentityInfo<FieldLimit> {
/// type FieldsIdentifier = u64;
///
/// fn has_identity(&self, fields: Self::FieldsIdentifier) -> bool {
/// self.fields().bits() & fields == fields
/// }
///
/// #[cfg(feature = "runtime-benchmarks")]
/// fn create_identity_info() -> Self {
/// let data = Data::Raw(vec![0; DEFAULT_DATA_MAX_LENGTH].try_into().unwrap());
/// let bio_data = Data::Raw(vec![0; BIO_DATA_MAX_LENGTH].try_into().unwrap());
///
/// IdentityInfo {
/// additional: vec![(data.clone(), data.clone()); FieldLimit::get().try_into().unwrap()]
/// .try_into()
/// .unwrap(),
/// display: data.clone(),
/// first_name: data.clone(),
/// last_name: data.clone(),
/// email: data.clone(),
/// address: data.clone(),
/// telephone_number: data.clone(),
/// bio: bio_data.clone(),
/// }
/// }
///
/// #[cfg(feature = "runtime-benchmarks")]
/// fn all_fields() -> Self::FieldsIdentifier {
/// IdentityField::all().bits()
/// }
/// }
#[macro_export]
macro_rules! generate_identity_information_provider_impl {
($type_name:ident, $field_limit:ident, $(($field_name:ident, $data_length:expr)),* $(,)?) => {
impl<$field_limit: Get<u32> + 'static> IdentityInformationProvider for $type_name<$field_limit> {
type FieldsIdentifier = u64;
fn has_identity(&self, fields: Self::FieldsIdentifier) -> bool {
self.fields().bits() & fields == fields
}
#[cfg(feature = "runtime-benchmarks")]
fn create_identity_info() -> Self {
$(
let $field_name = {
let data_length = $data_length;
Data::Raw(vec![0; data_length].try_into().unwrap())
};
)*
$type_name {
additional: vec![
(
Data::Raw(vec![0; DEFAULT_DATA_MAX_LENGTH].try_into().unwrap()),
Data::Raw(vec![0; DEFAULT_DATA_MAX_LENGTH].try_into().unwrap())
);
$field_limit::get() as usize
]
.try_into()
.unwrap(),
$(
$field_name: $field_name.clone(),
)*
}
}
#[cfg(feature = "runtime-benchmarks")]
fn all_fields() -> Self::FieldsIdentifier {
IdentityField::all().bits()
}
}
};
}
/// Macro for generating impl<FieldLimit: Get<u32>> Default for IdentityInfo<FieldLimit>
/// E.g.
///
/// impl<FieldLimit: Get<u32>> Default for IdentityInfo<FieldLimit> {
/// fn default() -> Self {
/// IdentityInfo {
/// additional: BoundedVec::default(),
/// display: Data::None,
/// first_name: Data::None,
/// last_name: Data::None,
/// email: Data::None,
/// address: Data::None,
/// telephone_number: Data::None,
/// bio: Data::None,
/// }
/// }
/// }
#[macro_export]
macro_rules! generate_identity_info_default_impl {
($(($field_name:ident, $default_value:expr)),*) => {
impl<FieldLimit: Get<u32>> Default for IdentityInfo<FieldLimit> {
fn default() -> Self {
IdentityInfo {
$(
$field_name: $default_value,
)*
}
}
}
};
}
/// Macro for generating impl<FieldLimit: Get<u32>> IdentityInfo<FieldLimit>
/// E.g.
///
/// impl<FieldLimit: Get<u32>> IdentityInfo<FieldLimit> {
/// pub(crate) fn fields(&self) -> BitFlags<IdentityField> {
/// let mut res = <BitFlags<IdentityField>>::empty();
/// if !self.display.is_none() {
/// res.insert(IdentityField::Display);
/// }
/// if !self.first_name.is_none() {
/// res.insert(IdentityField::FirstName);
/// }
/// if !self.last_name.is_none() {
/// res.insert(IdentityField::LastName);
/// }
/// if !self.email.is_none() {
/// res.insert(IdentityField::Email);
/// }
/// if !self.address.is_none() {
/// res.insert(IdentityField::Address);
/// }
/// if !self.telephone_number.is_none() {
/// res.insert(IdentityField::TelephoneNumber);
/// }
/// if !self.bio.is_none() {
/// res.insert(IdentityField::Bio);
/// }
/// res
/// }
/// }
#[macro_export]
macro_rules! generate_identity_info_impl {
($(($field_name:ident, $variant_name:ident)),*) => {
impl<FieldLimit: Get<u32>> IdentityInfo<FieldLimit> {
pub(crate) fn fields(&self) -> BitFlags<IdentityField> {
let mut res = <BitFlags<IdentityField>>::empty();
$(
if !self.$field_name.is_none() {
res.insert(IdentityField::$variant_name);
}
)*
res
}
}
};
}
// combined
#[macro_export]
macro_rules! generate_identity_field_enum_and_type_info {
($($variant:ident),+ $(,)?) => {
generate_identity_field_enum!(
$($variant),+
);
generate_type_info!(
IdentityField,
vec![
$(stringify!($variant)),+
]
);
}
}
#[macro_export]
macro_rules! generate_identity_info_impls {
(
$struct_name:ident,
$field_limit:ident,
$(($variant_name:ident, $field_name:ident, $max_length:expr)),+ $(,)?
) => {
generate_identity_information_provider_impl!(
$struct_name,
$field_limit,
$(($field_name, $max_length)),+
);
generate_identity_info_default_impl!(
(additional, BoundedVec::default()),
$(($field_name, Data::None)),+
);
generate_identity_info_impl!(
$(($field_name, $variant_name)),+
);
}
}