英文:
How can I mock a Macro attribute in Rust
问题
如何在Rust中进行测试时模拟一个宏属性,是否有某个库可以简化这个过程?
例如,#[my_macro]
修改了一个结构体,应用了另一个宏 #[account()]
到其中的一个字段,这个宏不在我的库中存在,但存在于使用我的宏的程序中:
// lib.rs
extern crate proc_macro;
use proc_macro::TokenStream;
mod macros;
#[proc_macro_attribute]
pub fn my_macro(args: TokenStream, input: TokenStream) -> TokenStream {
proc_macro::TokenStream::from(quote!(
pub struct MyModifiedStruct{
#[account()]
pub field1: u8
}
))
}
现在,如何在不为我的库中的#[account()]
依赖项而导致错误的情况下测试my_macro
?
// tests/my_test.rs
#[test]
fn test_my_macro() {
#[my_macro]
pub struct MyStruct{}
let my_struct = MyStruct{field1:1}
assert_eq!(my_struct.field1, 1)
}
在Python中,我通常会模拟#[account()]
属性,但不确定如何在Rust中进行这样的操作。
英文:
How can I mock a macro attribute when testing in Rust, is there some library to facilitate this?
For instance #[my_macro]
modifies a struct applying another macro #[account()]
to one of his fields, this macro doesn't exist in my library but exists in the programs which are using my macro:
// lib.rs
extern crate proc_macro;
use proc_macro::TokenStream;
mod macros;
#[proc_macro_attribute]
pub fn my_macro(args: TokenStream, input: TokenStream) -> TokenStream {
proc_macro::TokenStream::from(quote!(
pub struct MyModifiedStruct{
#[account()]
pub field1: u8
}
))
}
Now how can I test my_macro without getting an error for not having the #[account()]
dependency in my library?
// tests/my_test.rs
#[test]
fn test_my_macro() {
#[my_macro]
pub struct MyStruct{}
let my_struct = MyStruct{field1:1}
assert_eq!(my_struct.field1, 1)
}
My normal approach in Python would be mocking the #[account()]
attribute, but not sure how can that be done in Rust.
答案1
得分: 1
我通常在Python中的正常方法是模拟 #[account()]
属性,但不确定如何在Rust中实现。
你可以在与 #[my_macro]
定义相同的 proc-macro crate 中实现 #[account]
属性宏的模拟版本,并将其导入到你在使用 #[my_macro]
的范围内:
lib.rs:
extern crate proc_macro;
use proc_macro::TokenStream;
mod macros;
#[proc_macro_attribute]
pub fn my_macro(args: TokenStream, input: TokenStream) -> TokenStream {
proc_macro::TokenStream::from(quote!(
pub struct MyModifiedStruct{
#[account()]
pub field1: u8
}
))
}
#[proc_macro_attribute]
pub fn account(_args: TokenStream, input: TokenStream) -> TokenStream {
input
}
tests/my_test.rs:
// tests/my_test.rs
use your_crate::{my_macro, account};
#[test]
fn test_my_macro() {
#[my_macro]
pub struct MyStruct{}
let my_struct = MyStruct{field1:1}
assert_eq!(my_struct.field1, 1)
}
英文:
> My normal approach in Python would be mocking the #[account()]
attribute, but not sure how can that be done in Rust.
You could implement a mock version of your #[account]
attribute macro in the same proc-macro crate as #[my_macro]
is defined and import it into the scope you are using #[my_macro]
in:
lib.rs:
extern crate proc_macro;
use proc_macro::TokenStream;
mod macros;
#[proc_macro_attribute]
pub fn my_macro(args: TokenStream, input: TokenStream) -> TokenStream {
proc_macro::TokenStream::from(quote!(
pub struct MyModifiedStruct{
#[account()]
pub field1: u8
}
))
}
#[proc_macro_attribute]
pub fn account(_args: TokenStream, input: TokenStream) -> TokenStream {
input
}
tests/my_test.rs:
// tests/my_test.rs
use your_crate::{my_macro, account};
#[test]
fn test_my_macro() {
#[my_macro]
pub struct MyStruct{}
let my_struct = MyStruct{field1:1}
assert_eq!(my_struct.field1, 1)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论