7 个不稳定版本
使用旧的Rust 2015
0.4.0 | 2021年2月25日 |
---|---|
0.3.0 | 2020年2月15日 |
0.2.1 | 2018年1月22日 |
0.1.2 | 2016年1月19日 |
0.1.1 | 2015年5月9日 |
#1722 in 进程宏
用于 sofia-sip
26KB
533 行
rust-adorn
Rust的Python风格函数装饰器
装饰函数
示例用法
use adorn::{adorn, make_decorator};
#[adorn(bar)]
fn foo(a: &mut u8, b: &mut u8, (c, _): (u8, u8)) {
assert!(c == 4);
*a = c;
*b = c;
}
fn bar<F>(f: F, a: &mut u8, b: &mut u8, (c, d): (u8, u8)) where F: Fn(&mut u8, &mut u8, (u8, u8)) {
assert!(c == 0 && d == 0);
f(a, b, (4, 0));
*b = 100;
}
fn main() {
let mut x = 0;
let mut y = 1;
foo(&mut x, &mut y, (0, 0));
assert!(x == 4 && y == 100);
}
在这种情况下,foo
将变成
fn foo(a: &mut u8, b: &mut u8, (c, d): (u8, u8)) {
fn foo_inner(a: &mut u8, b: &mut u8, (c, _): (u8, u8)) {
assert!(c == 4);
*a = c;
*b = c;
}
bar(foo_inner, a, b, (c, d))
}
换句话说,调用 foo()
实际上会调用 bar()
,它围绕 foo()
包装。
有一个 #[make_decorator]
属性,作为创建装饰器的糖语法。例如,
#[make_decorator(f)]
fn bar(a: &mut u8, b: &mut u8, (c, d): (u8, u8)) {
assert!(c == 0 && d == 0);
f(a, b, (4, 0)); // `f` was declared in the `make_decorator` annotation
*b = 100;
}
转换为
fn bar<F>(f: F, a: &mut u8, b: &mut u8, (c, d): (u8, u8)) where F: Fn(&mut u8, &mut u8, (u8, u8)) {
assert!(c == 0 && d == 0);
f(a, b, (4, 0));
*b = 100;
}
装饰非静态方法
示例用法
use adorn::{adorn_method, make_decorator_method};
pub struct Test {
a: u8,
b: u8
}
impl Test {
#[adorn_method(bar)]
fn foo(&mut self, a: u8, b: u8) {
assert!(a == 0 && b == 0);
self.a = a;
self.b = b;
}
fn bar<F>(&mut self, f: F, a: u8, b: u8) where F: Fn(Self, u8, u8) {
assert!(a == 0 && b == 0);
f(self, a, b);
self.b = 100;
}
}
fn main() {
let mut t = Test {
a: 1,
b: 1,
};
t.foo(0, 0);
assert!(t.a == 0 && t.b == 100);
}
在这种情况下,foo
将变成
impl Test {
fn foo(&mut self, a: u8, b: u8) {
let foo_inner = |s: &mut Self, a: u8, b: u8| {
assert!(a == 0 && b == 0);
s.a = a;
s.b = b;
};
self.bar(foo_inner, a, b, (c, d))
}
}
类似地,提供了一个 #[make_decorator_method]
属性来创建装饰器。例如,
impl Test {
#[make_decorator_method(f)]
fn bar(&mut self, a: u8, b: u8) {
assert!(a == 0 && b == 0);
f(self, a, b); // `f` was declared in the `make_decorator_method` annotation
self.b = 100;
}
}
转换为
impl Test{
fn bar<F>(&mut self, f: F, a: u8, b: u8) where F: Fn(Self, u8, u8) {
assert!(a == 0 && b == 0);
f(self, a, b);
self.b = 100;
}
}
装饰静态方法
使用 #[make_decorator_static]
和 #[adorn_static]
创建一个静态装饰器,然后将其用于装饰静态方法,例如
use adorn::{adorn_method, make_decorator_method};
pub struct Test {
a: u8,
b: u8
}
impl Test {
#[adorn_static(bar)]
fn foo(a: u8, b: u8) -> Self {
assert!(a == 0 && b == 0);
Self {
a,
b
}
}
#[make_decorator_static(f)]
fn bar(a: u8, b: u8) -> Self {
assert!(a == 0 && b == 0);
let mut retval = f(a, b);
retval.b = 100;
retval
}
}
fn main() {
let t = Test::foo(0, 0);
assert!(t.a == 0 && t.b == 100);
}
这两个静态方法转换为
impl Test {
fn foo(a: u8, b: u8) -> Self {
let foo_inner = |a: u8, b: u8| -> Self {
assert!(a == 0 && b == 0);
Self {
a,
b
}
};
Self::bar(foo, a, b)
}
fn bar(f: F, a: u8, b: u8) -> Self where F: Fn(u8, u8) -> Self {
assert!(a == 0 && b == 0);
let mut retval = f(a, b);
retval.b = 100;
retval
}
}
依赖
~2MB
~47K SLoC