5个版本
0.1.8 | 2020年7月10日 |
---|---|
0.1.7 | 2020年7月10日 |
0.1.5 | 2020年6月18日 |
#750 在 过程宏 中
每月26次 下载
29KB
423 代码行
Yui
Yui是Rust的属性读取器。
特性
属性结构
Yui提供了一个 derive 宏 YuiAttribute
,可以通过 struct(结构体)、StructStruct
、TupleStruct
和 NoFieldStruct
创建属性结构,所有这些都被支持。
use yui::YuiAttribute;
#[derive(YuiAttribute)]
struct NoField;
#[derive(YuiAttribute)]
struct Tuple(i32, String);
#[derive(YuiAttribute)]
struct Struct {
int: i32,
float: f64,
bool: bool,
}
类型
- String:Rust中的
String
。 - Bool:Rust中的
bool
。 - Integer:Rust中的任何整数类型。
- Float:Rust中的任何浮点类型。
- Object:其他属性结构。
- Enum:定义枚举,请记得使用
enum_value=true
选项。 - Vec:T的Vec(T不能是Object、Vec或HashMap)。
- HashMap
:通过 String
Skey 映射T的HashMap。如果你想要使一个字段可选,在字段类型上使用Option<T>
。
use yui::{YuiEnumValue, YuiAttribute};
#[derive(YuiAttribute)]
struct Bar;
#[derive(YuiEnumValue)]
enum SomeEnum {
A,
B
}
#[derive(YuiAttribute)]
struct Foo {
pub string: String,
pub bool: bool,
pub int: i32, // or other integer types like u32 ...
pub float: f32, // or other float types like f64
pub object: Bar, // any defined object
#[attribute_field(enum_value=true)]
pub enum_field: SomeEnum, // have to add enum_value option
pub list: Vec<i32>, // nested type of vec can`t be Object, Vec or HashMap
pub map: std::collections::HashMap<String, SomeEnum>,
pub optional: Option<i32> // optional field
}
选项
alias
生成的读取器将使用给定的名称解析字段,而不是Rust中字段的名称。#[derive(YuiAttribute)] struct Foo { #[attribute_field(alias = "i32")] pub int32: i32, }
default
为此字段设置默认值。如果解析时不存在该值,则将默认值设置为字段,即使该字段是可选的。Object
、Vec
或HashMap
字段不能有默认值。#[derive(YuiAttribute)] struct Foo { #[attribute_field(default = 1024)] pub int32: i32 }
enum_value
在Enum类型字段上使用enum_value=true
。
Enum
使用 derive YuiEnumValue
在 Enum 上创建一个 Enum 值类型。
use yui::YuiEnumValue;
#[derive(YuiEnumValue)]
enum SomeEnum {
A,
B
}
然后,枚举可以作为一个字段类型使用。
variant_value
属性
自定义与变体对应的字符串值(默认是Rust中变体名称的蛇形命名法)。
use yui::YuiEnumValue;
#[derive(YuiEnumValue)]
enum SomeEnum {
#[variant_value("aaa")] // default is 'a'
A,
B
}
使用 syn
和 quote
解析属性
yui::AttributeStructs<T>
可用于 parse_macro_input!
let attributes = syn::parse_macro_inpit!(input as yui::AttributeStructs<Foo>);
如果您想从 syn::Meta
解析属性,请使用 yui::AttributeStruct::from_meta()
。
带有值的属性结构可以自动转换为令牌。但是每个字段的可见性必须是公共的。
use proc_macro::TokenStream;
#[derive(YuiAttribute)]
struct Foo {
#[attribute_field(default = 1024)]
pub int32: i32
}
fn derive_fn(input: TokenStream) -> TokenStream {
let attributes = syn::parse_macro_input!(input as yui::AttributeStructs<Foo>);
let attrs = attributes.attrs;
TokenStream::from(quote::quote! {
fn get_attrs() -> Vec<Foo> {
vec![#(#attrs),*]
}
})
}
生成 derive 宏
如果您想使用内置的读取生成器,请启用 generate-reader
功能。宏 generate_reader
用于生成 derive 宏。
use yui::generate_reader;
generated_reader!(
MyDerive,
[StructAttribute1, StructAttribute2],
[FieldAttribute1, FieldAttribute2]
);
该宏将生成一个公共的 derive,它可以用于读取 struct
、enum
或 union
的属性,并通过生成 impl
块来记录元数据。
读取属性
在结构体上使用生成的 derive 宏,并可以使用宏 has_attribute
和 get_attribute
处理结构体的属性。该功能需要 nightly rustc,因为需要 proc_macro_hygiene
。
#![feature(proc_macro_hygiene)]
use yui::{get_attribute, has_attribute};
#[derive(MyDerive)]
#[StructAttribute1("some parameters")]
struct Foo {
#[FieldAttribute1("some parameters")]
field: i32
}
fn some_fn() {
assert!(has_attribute!(Foo, StructAttribute1));
assert!(has_attribute!(Foo::field, FieldAttribute1));
let struct_attr1: Option<StructAttribute1> = get_attribute!(Foo, StructAttribute1);
let field_attr1: Option<StructAttribute1> = get_attribute!(Foo::field, StructAttribute1);
}
依赖项
~2MB
~43K SLoC