10个稳定版本
1.3.2 | 2024年5月27日 |
---|---|
1.2.1 | 2024年5月26日 |
1.1.2 | 2023年7月9日 |
1.0.1 | 2023年7月5日 |
#163 在 过程宏
63 每月下载量
27KB
314 行
fn-decorator
该包包含实现围绕成员或静态函数的包装函数的宏。
使用 use_decorator
装饰器函数
fn decorator(f: fn() -> i64) -> i64 {
f() + 1
}
装饰函数
#[use_decorator(decorator())]
fn get_1() -> i64 {
1
}
当调用 get_1()
时,则会执行 decorator(get_1)
。装饰器函数可以决定是否调用接收到的函数。
还有一个 use_impl_decorator
宏,它可以在 impl
块中使用。
这两个宏可以有相同的参数
- 要执行的装饰器函数调用。这可以包含参数。请参阅示例以了解确切用法!
hide_parameters = [...]
:如果装饰器函数签名与被装饰函数不匹配,则可以使用此列表来隐藏装饰器函数的一些参数。请注意,不能同时提供hide_parameters
和exact_parameters
。exact_parameters = [...]
:如果装饰器函数签名与被装饰函数不匹配,则可以使用此列表来指定要传递给装饰器函数的精确参数。请注意,不能同时提供hide_parameters
和exact_parameters
。override_return_type = <type>
:如果装饰器返回类型与被装饰函数不匹配,则可以使用此列表来更改被装饰函数的返回类型debug
:当给出此参数时,代码将生成编译错误和生成的源代码。这有助于调试。
完整工作示例
装饰无参数函数
use fn_decorator::use_decorator;
fn decorator(f: fn() -> i64) -> i64 {
f() + 1
}
#[use_decorator(decorator())]
fn get_1() -> i64 {
1
}
#[test]
fn fn_without_params_decorator() {
let result = get_1();
assert_eq!(result, 2);
}
装饰有参数的函数
use fn_decorator::use_decorator;
fn decorator(f: fn(x: i64) -> i64, x: i64) -> i64 {
f(x) * 2
}
#[use_decorator(decorator())]
fn double(x: i64) -> i64 {
x * 2
}
#[test]
fn decorator_without_params() {
let result = double(2);
assert_eq!(result, 8);
}
使用参数化装饰器函数
use fn_decorator::use_decorator;
fn decorator(
middle: String,
f: fn(String, String) -> String,
left: String,
right: String,
) -> String {
let left = left + &middle;
f(left, right)
}
#[use_decorator(decorator("_middle_".to_string()))]
fn concat(left: String, right: String) -> String {
left + &right
}
#[test]
fn decorator_with_param() {
let result = concat("left".into(), "right".into());
assert_eq!(result, "left_middle_right");
}
调试fn装饰器
请注意,测试中不包含此代码,因为它会产生编译时错误。
use fn_decorator::use_decorator;
fn decorator(f: fn() -> i64) -> i64 {
f() + 1
}
#[use_decorator(decorator(), debug)]
fn get_1() -> i64 {
1
}
#[test]
fn debug_fn_decorator() {
let result = get_1();
assert_eq!(result, 2);
}
装饰成员函数
use fn_decorator::use_impl_decorator;
fn decorator(f: fn(&MyStruct, y: i64) -> i64, receiver: &MyStruct, y: i64) -> i64 {
f(receiver, y) + 1
}
struct MyStruct {
x: i64,
}
impl MyStruct {
#[use_impl_decorator(decorator())]
fn add(&self, y: i64) -> i64 {
self.x + y
}
}
#[test]
fn impl_member_decorator() {
let obj = MyStruct { x: 1 };
let result = obj.add(1);
assert_eq!(result, 3);
}
装饰静态成员函数
use fn_decorator::use_impl_decorator;
fn decorator(f: fn(x: i64) -> i64, x: i64) -> i64 {
f(x) + 1
}
struct MyStruct;
impl MyStruct {
#[use_impl_decorator(decorator())]
fn double(x: i64) -> i64 {
x * 2
}
}
#[test]
fn impl_static_member_decorator() {
let result = MyStruct::double(2);
assert_eq!(result, 5);
}
装饰异步函数
use std::future::Future;
use fn_decorator::use_decorator;
async fn decorator<FutureType: Future<Output = i64>>(f: fn(x: i64) -> FutureType, x: i64) -> i64 {
f(x).await * 2
}
#[use_decorator(decorator())]
async fn double(x: i64) -> i64 {
x * 2
}
#[tokio::test]
async fn async_decorator() {
let result = double(2).await;
assert_eq!(result, 8);
}
使用异步函数指定异步装饰器的确切参数列表
use std::future::Future;
use fn_decorator::use_decorator;
async fn decorator<FutureType: Future<Output = String>>(
middle: String,
f: impl FnOnce(String) -> FutureType,
right: String,
) -> String {
let right = middle + &right;
f(right).await
}
#[use_decorator(decorator("_middle_".to_string()), exact_parameters = [right])]
async fn concat(left: String, right: String) -> String {
left + &right
}
#[tokio::test]
async fn hiding_params_of_async_fn_decorator() {
let result = concat("left".into(), "right".into()).await;
assert_eq!(result, "left_middle_right");
}
使用异步成员函数指定异步装饰器的确切参数列表
use std::future::Future;
use fn_decorator::use_impl_decorator;
async fn decorator<'a, FutureType: Future<Output = &'a String>>(
middle: String,
f: impl FnOnce(&'a mut MyStruct) -> FutureType,
receiver: &'a mut MyStruct,
) -> &'a String {
receiver.left.push_str(&middle);
f(receiver).await
}
struct MyStruct {
left: String,
}
impl MyStruct {
#[use_impl_decorator(decorator("_middle_".to_string()), exact_parameters = [self])]
async fn concat(&mut self, right: String) -> &String {
self.left.push_str(&right);
&self.left
}
}
#[tokio::test]
async fn hiding_params_of_async_impl_member_decorator() {
let mut obj = MyStruct {
left: "left".into(),
};
let result = obj.concat("right".into()).await;
assert_eq!(result, "left_middle_right");
}
使用函数指定装饰器的确切参数列表
use fn_decorator::use_decorator;
fn decorator(middle: String, f: impl FnOnce(String) -> String, right: String) -> String {
let right = middle + &right;
f(right)
}
#[use_decorator(decorator("_middle_".to_string()), exact_parameters = [right])]
fn concat(left: String, right: String) -> String {
left + &right
}
#[test]
fn hiding_params_of_fn_decorator() {
let result = concat("left".into(), "right".into());
assert_eq!(result, "left_middle_right");
}
使用成员函数指定装饰器的确切参数列表
use fn_decorator::use_impl_decorator;
fn decorator(middle: String, f: impl FnOnce(&MyStruct) -> String, receiver: &MyStruct) -> String {
let new_struct = MyStruct {
left: receiver.left.clone() + &middle,
};
f(&new_struct)
}
struct MyStruct {
left: String,
}
impl MyStruct {
#[use_impl_decorator(decorator("_middle_".to_string()), exact_parameters = [self])]
fn concat(&self, right: String) -> String {
self.left.clone() + &right
}
}
#[test]
fn hiding_params_of_impl_member_decorator() {
let obj = MyStruct {
left: "left".into(),
};
let result = obj.concat("right".into());
assert_eq!(result, "left_middle_right");
}
#[test] fn hiding_self_param_in_impl_member_decorator() { let obj = MyStruct { left: "left".into(), }; let result = obj.concat("right".into()); assert_eq!(result, "left_middle_right"); }
### Hiding parameters of an async function from a decorator
```rust
use std::future::Future;
use fn_decorator::use_decorator;
async fn decorator<FutureType: Future<Output = String>>(
middle: String,
f: impl FnOnce(String) -> FutureType,
right: String,
) -> String {
let right = middle + &right;
f(right).await
}
#[use_decorator(decorator("_middle_".to_string()), hide_parameters = [left])]
async fn concat(left: String, right: String) -> String {
left + &right
}
#[tokio::test]
async fn hiding_params_of_async_fn_decorator() {
let result = concat("left".into(), "right".into()).await;
assert_eq!(result, "left_middle_right");
}
从装饰器中隐藏异步成员函数的参数
use std::future::Future;
use fn_decorator::use_impl_decorator;
async fn decorator<'a, FutureType: Future<Output = &'a String>>(
middle: String,
f: impl FnOnce(&'a mut MyStruct) -> FutureType,
receiver: &'a mut MyStruct,
) -> &'a String {
receiver.left.push_str(&middle);
f(receiver).await
}
struct MyStruct {
left: String,
}
impl MyStruct {
#[use_impl_decorator(decorator("_middle_".to_string()), hide_parameters = [right])]
async fn concat(&mut self, right: String) -> &String {
self.left.push_str(&right);
&self.left
}
}
#[tokio::test]
async fn hiding_params_of_async_impl_member_decorator() {
let mut obj = MyStruct {
left: "left".into(),
};
let result = obj.concat("right".into()).await;
assert_eq!(result, "left_middle_right");
}
从装饰器中隐藏函数的参数
use fn_decorator::use_decorator;
fn decorator(middle: String, f: impl FnOnce(String) -> String, right: String) -> String {
let right = middle + &right;
f(right)
}
#[use_decorator(decorator("_middle_".to_string()), hide_parameters = [left])]
fn concat(left: String, right: String) -> String {
left + &right
}
#[test]
fn hiding_params_of_fn_decorator() {
let result = concat("left".into(), "right".into());
assert_eq!(result, "left_middle_right");
}
从装饰器中隐藏成员函数的参数
use fn_decorator::use_impl_decorator;
fn decorator(middle: String, f: impl FnOnce(&MyStruct) -> String, receiver: &MyStruct) -> String {
let new_struct = MyStruct {
left: receiver.left.clone() + &middle,
};
f(&new_struct)
}
struct MyStruct {
left: String,
}
impl MyStruct {
#[use_impl_decorator(decorator("_middle_".to_string()), hide_parameters = [right])]
fn concat(&self, right: String) -> String {
self.left.clone() + &right
}
}
#[test]
fn hiding_params_of_impl_member_decorator() {
let obj = MyStruct {
left: "left".into(),
};
let result = obj.concat("right".into());
assert_eq!(result, "left_middle_right");
}
从装饰器中隐藏成员函数的self
use fn_decorator::use_impl_decorator;
fn decorator(middle: String, f: impl FnOnce(String) -> String, right: String) -> String {
let right = middle + &right;
f(right)
}
struct MyStruct {
left: String,
}
impl MyStruct {
#[use_impl_decorator(decorator("_middle_".to_string()), hide_parameters = [self])]
fn concat(&self, right: String) -> String {
self.left.clone() + &right
}
}
#[test]
fn hiding_self_param_in_impl_member_decorator() {
let obj = MyStruct {
left: "left".into(),
};
let result = obj.concat("right".into());
assert_eq!(result, "left_middle_right");
}
装饰异步成员函数
use std::future::Future;
use fn_decorator::use_impl_decorator;
async fn decorator<'a, FutureType: Future<Output = i64>>(
f: fn(&'a MyStruct, y: i64) -> FutureType,
receiver: &'a MyStruct,
y: i64,
) -> i64 {
f(receiver, y).await + 1
}
struct MyStruct {
x: i64,
}
impl MyStruct {
#[use_impl_decorator(decorator())]
async fn add(&self, y: i64) -> i64 {
self.x + y
}
}
#[tokio::test]
async fn async_impl_member_decorator() {
let obj = MyStruct { x: 1 };
let result = obj.add(1).await;
assert_eq!(result, 3);
}
装饰异步静态成员函数
use std::future::Future;
use fn_decorator::use_impl_decorator;
async fn decorator<FutureType: Future<Output = i64>>(f: fn(y: i64) -> FutureType, x: i64) -> i64 {
f(x).await + 1
}
struct MyStruct;
impl MyStruct {
#[use_impl_decorator(decorator())]
async fn double(x: i64) -> i64 {
x * 2
}
}
#[tokio::test]
async fn async_impl_member_decorator() {
let result = MyStruct::double(2).await;
assert_eq!(result, 5);
}
重写返回类型
use fn_decorator::use_decorator;
fn decorator(f: fn() -> i64) -> Result<i64, ()> {
Ok(f() + 1)
}
#[use_decorator(decorator(), override_return_type = Result<i64, ()>)]
fn get_1() -> i64 {
1
}
#[use_decorator(decorator(), override_return_type = impl ::std::any::Any)]
fn get_2() -> i64 {
2
}
#[test]
fn overriding_return_type() {
let result = get_1();
assert_eq!(result, Ok(2));
let result = get_2();
assert_eq!("core::result::Result<i64, ()>", ::std::any::type_name_of_val(&result));
}
依赖关系
~290–740KB
~18K SLoC