Rust宏编程库pallet-revive-proc-macro的使用:高效代码生成与过程宏扩展
Rust宏编程库pallet-revive-proc-macro的使用:高效代码生成与过程宏扩展
安装
在项目目录中运行以下Cargo命令:
cargo add pallet-revive-proc-macro
或者在你的Cargo.toml中添加以下行:
pallet-revive-proc-macro = "0.3.1"
示例代码
以下是一个使用pallet-revive-proc-macro的完整示例:
// 引入proc_macro库
use proc_macro::TokenStream;
use pallet_revive_proc_macro::revive;
// 定义一个简单的结构体
#[revive]
struct MyStruct {
field1: u32,
field2: String,
}
// 使用宏生成的代码
#[test]
fn test_revive_macro() {
let my_struct = MyStruct {
field1: 42,
field2: "hello".to_string(),
};
// 宏会自动为结构体生成特定的方法
let serialized = my_struct.serialize();
let deserialized = MyStruct::deserialize(&serialized).unwrap();
assert_eq!(my_struct.field1, deserialized.field1);
assert_eq!(my_struct.field2, deserialized.field2);
}
// 宏也可以用于枚举
#[revive]
enum MyEnum {
Variant1(u32),
Variant2 { name: String, value: i64 },
}
// 使用宏生成的枚举方法
#[test]
fn test_enum_macro() {
let variant1 = MyEnum::Variant1(123);
let variant2 = MyEnum::Variant2 {
name: "test".to_string(),
value: -456,
};
assert_eq!(variant1.serialize().len(), 5);
assert!(variant2.deserialize(&variant2.serialize()).is_ok());
}
完整示例demo
下面是一个更完整的示例,展示如何在Substrate pallet开发中使用这个宏:
// 引入必要的库
use proc_macro::TokenStream;
use pallet_revive_proc_macro::revive;
use frame_support::pallet_prelude::*;
// 定义一个复杂的结构体用于存储账户信息
#[revive]
#[derive(Clone, Encode, Decode, PartialEq, Debug, TypeInfo)]
pub struct AccountData<Balance> {
pub free: Balance,
pub reserved: Balance,
pub misc: MiscData,
}
// 嵌套的结构体也需要使用宏
#[revive]
#[derive(Clone, Encode, Decode, PartialEq, Debug, TypeInfo)]
pub struct MiscData {
pub is_active: bool,
pub last_update: u64,
}
// 定义一个复杂枚举
#[revive]
#[derive(Clone, Encode, Decode, PartialEq, Debug, TypeInfo)]
pub enum AccountEvent<AccountId, Balance> {
Created(AccountId),
BalanceSet { who: AccountId, amount: Balance },
Destroyed(AccountId),
}
// 测试用例
#[test]
fn test_complex_types() {
// 测试结构体
let account_data = AccountData {
free: 100u32,
reserved: 50u32,
misc: MiscData {
is_active: true,
last_update: 123456789,
},
};
let serialized = account_data.serialize();
let deserialized = AccountData::deserialize(&serialized).unwrap();
assert_eq!(account_data, deserialized);
// 测试枚举
let event = AccountEvent::BalanceSet {
who: 1u64,
amount: 200u32,
};
let event_serialized = event.serialize();
let event_deserialized = AccountEvent::deserialize(&event_serialized).unwrap();
assert_eq!(event, event_deserialized);
}
功能说明
pallet-revive-proc-macro库提供了以下主要功能:
- 自动为结构体和枚举生成序列化/反序列化方法
- 简化Substrate pallet开发中的常见模式
- 提供高效的类型转换和代码生成
许可证
Apache-2.0
1 回复
Rust宏编程库pallet-revive-proc-macro的使用:高效代码生成与过程宏扩展
完整示例demo
以下是结合了内容中所有示例功能的完整demo:
// 引入必要的库和宏
use pallet_revive_proc_macro::{Revive, revive};
use serde_json;
// 1. 基础派生宏使用示例
#[derive(Revive)]
struct User {
id: u64,
username: String,
is_active: bool,
}
// 2. 自定义属性宏示例
#[revive(name = "UserUtils", version = 1)]
impl User {
fn create_guest() -> Self {
Self {
id: 0,
username: "guest".to_string(),
is_active: true,
}
}
}
// 3. 代码生成示例 - 生成builder模式
#[derive(Revive)]
#[revive(generate_builder)]
struct Product {
id: u32,
name: String,
price: f64,
#[revive(default = "vec![]")]
tags: Vec<String>,
}
// 4. 元编程扩展示例 - 自动实现Serialize
#[revive(extend = "serde::Serialize")]
#[derive(Revive)]
struct Order {
order_id: String,
items: Vec<Product>,
total: f64,
}
// 5. 条件编译支持示例
#[derive(Revive)]
#[revive(feature = "debug", generate_debug)]
struct Config {
#[revive(skip)]
secret_key: String,
api_url: String,
timeout: u64,
}
// 6. 自定义扩展示例
use pallet_revive_proc_macro::ReviveExtension;
use syn;
use quote::quote;
struct TimestampExtension;
impl ReviveExtension for TimestampExtension {
fn extend(&self, ast: &mut syn::DeriveInput) -> proc_macro2::TokenStream {
let name = &ast.ident;
quote! {
impl #name {
pub fn timestamp(&self) -> u64 {
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs()
}
}
}
}
}
#[derive(Revive)]
#[revive(extension = "TimestampExtension")]
struct LogEntry {
message: String,
level: u8,
}
fn main() {
// 使用生成的builder创建Product实例
let product = Product::builder()
.id(1)
.name("Rust Programming Book".to_string())
.price(39.99)
.build();
println!("Product: {:?}", product);
// 使用自动实现的Serialize
let order = Order {
order_id: "ORD-123".to_string(),
items: vec![product],
total: 39.99,
};
let json = serde_json::to_string(&order).unwrap();
println!("Order JSON: {}", json);
// 使用自定义扩展生成的方法
let log = LogEntry {
message: "System started".to_string(),
level: 1,
};
println!("Log created at: {}", log.timestamp());
// 条件编译功能测试
#[cfg(feature = "debug")]
{
let config = Config {
secret_key: "abc123".to_string(),
api_url: "https://api.example.com".to_string(),
timeout: 30,
};
println!("Debug config: {:?}", config);
}
}
Cargo.toml配置示例
[package]
name = "revive-demo"
version = "0.1.0"
edition = "2021"
[dependencies]
pallet-revive-proc-macro = "0.1.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
syn = { version = "2.0", features = ["full"] }
quote = "1.0"
# 如果要测试条件编译功能,可以取消下面的注释
# [features]
# debug = []
这个完整示例展示了pallet-revive-proc-macro
库的主要功能:
- 基础派生宏
- 自定义属性宏
- 自动生成builder模式
- 元编程扩展自动实现trait
- 条件编译支持
- 自定义扩展功能
您可以根据实际需求选择使用其中的部分或全部功能。