#syn #macro-derive #parse #attributes #quote #boilerplate #complex

syn_derive

syn::Parsequote::ToTokens 提供派生宏

8个版本

0.1.8 2023年10月10日
0.1.7 2023年9月6日
0.1.6 2023年5月9日
0.1.5 2023年3月21日
0.1.2 2022年11月14日

256过程宏 中排名

Download history 188810/week @ 2024-03-14 184109/week @ 2024-03-21 187030/week @ 2024-03-28 231154/week @ 2024-04-04 207997/week @ 2024-04-11 203133/week @ 2024-04-18 195759/week @ 2024-04-25 192864/week @ 2024-05-02 206873/week @ 2024-05-09 200657/week @ 2024-05-16 189136/week @ 2024-05-23 226450/week @ 2024-05-30 213871/week @ 2024-06-06 208879/week @ 2024-06-13 214536/week @ 2024-06-20 180455/week @ 2024-06-27

858,056 每月下载量
用于 1,453 个crates (6 直接)

MIT/Apache

17KB
302

一个用于减少使用 syn 编写解析器时的样板代码的简单crate。

结构体

#[derive(Clone, Debug, syn_derive::Parse, syn_derive::ToTokens)]
struct ExampleStruct {
	#[parse(Attribute::parse_outer)]
	#[to_tokens(|tokens, val| tokens.append_all(val))]
	attrs: Vec<Attribute>,

	path: Path,

	#[syn(parenthesized)]
	paren_token: Paren,

	#[syn(in = brace_token)]
	#[parse(Punctuated::parse_terminated)]
	args: Punctuated<Box<Expr>, Token![,]>,

	semi_token: Token![;],
}

[syn(parenthesized)], [syn(braced)], [syn(bracketed)]:对应于 syn 中的同义词宏。必须分别附加到 ParenBraceBracket 字段。

#[syn(in = Ident)]:从命名的分隔符对内部读取字段。

#[parse(fn(ParseStream) -> syn::Result<T>)]:用于解析字段的函数,通常与 Punctuated::parse_terminatedAttribute::parse_outer 一起使用。

#[to_tokens(fn(&mut TokenStream, &T)]:用于分词字段的函数。通常与TokenStreamExt::append_all一起使用,但由于类型解析的原因,需要通过闭包表达式间接进行。

枚举

#[derive(Clone, Debug, syn_derive::Parse, syn_derive::ToTokens)]
enum ExampleEnum {
	#[parse(peek = Token![struct])]
	Struct(ItemStruct),
	#[parse(peek = Token![enum])]
	Enum(ItemEnum),

	Other {
		path: Path,
		semi_token: Token![;],
	}
}

#[parse(prefix = fn(ParseStream) -> syn::Result<_>)]:在预览之前用于所有分支的前缀。当所有分支都支持属性时很有用。返回值被忽略,这导致性能略差,因为前缀被解析了两次。

#[parse(peek = Token)]:检查是否应解析变体。即使多个预览成功,也只尝试第一个成功的变体。

#[parse(peek_func = fn(ParseStream) -> bool)]:比peek更强大(例如,允许peek2),但在失败时提供的错误信息较差。当可能时,应优先选择peek

功能标志

  • full(默认启用):启用syn/full,这在解析属性值中的复杂表达式(如闭包)时是必需的。如果没有这个,你仍然可以使用例如函数的路径,但这很不方便。

替代方案

  • derive-syn-parse不处理ToTokens。它似乎还鼓励通过其prefixpostfix属性丢弃标记。
  • parsel使用其自己的括号类型,这意味着AST类型与syn的API不同。

依赖关系

~315–770KB
~18K SLoC