Skip to main content

csskit_derives/
lib.rs

1use proc_macro::TokenStream;
2use syn::{DeriveInput, Generics, Result, parse_quote};
3
4mod attributes;
5mod css_feature;
6mod darling_ext;
7mod declaration_metadata;
8mod feature_metadata;
9mod field_view;
10mod into_cursor;
11mod node_with_metadata;
12mod parse;
13mod peek;
14mod semantic_eq;
15mod to_cursors;
16mod to_span;
17mod visitable;
18mod visitor;
19mod where_collector;
20
21use field_view::FieldsExt;
22use where_collector::WhereCollector;
23
24fn ensure_lifetime_a(generics: &Generics) -> Generics {
25	let mut g = generics.clone();
26	if generics.lifetimes().all(|l| l.lifetime.ident != "a") {
27		g.params.insert(0, parse_quote!('a));
28	}
29	g
30}
31
32#[cfg(test)]
33mod test;
34
35fn run<F>(stream: TokenStream, f: F) -> TokenStream
36where
37	F: FnOnce(DeriveInput) -> Result<proc_macro2::TokenStream>,
38{
39	let input = syn::parse::<DeriveInput>(stream).unwrap_or_else(|e| panic!("{e}"));
40	f(input).unwrap_or_else(|e| e.into_compile_error()).into()
41}
42
43#[proc_macro_derive(ToCursors, attributes(to_cursors))]
44pub fn derive_to_cursors(stream: TokenStream) -> TokenStream {
45	run(stream, to_cursors::derive)
46}
47
48#[proc_macro_derive(Parse, attributes(parse, atom))]
49pub fn derive_parse(stream: TokenStream) -> TokenStream {
50	run(stream, parse::derive)
51}
52
53#[proc_macro_derive(Peek, attributes(peek, atom))]
54pub fn derive_peek(stream: TokenStream) -> TokenStream {
55	run(stream, peek::derive)
56}
57
58#[proc_macro_derive(IntoCursor)]
59pub fn derive_into_cursor(stream: TokenStream) -> TokenStream {
60	run(stream, into_cursor::derive)
61}
62
63#[proc_macro_derive(ToSpan)]
64pub fn derive_into_span(stream: TokenStream) -> TokenStream {
65	run(stream, to_span::derive)
66}
67
68#[proc_macro_derive(Visitable, attributes(visit, queryable))]
69pub fn derive_visitable(stream: TokenStream) -> TokenStream {
70	run(stream, visitable::derive)
71}
72
73#[proc_macro_derive(FeatureMetadata, attributes(feature_metadata))]
74pub fn derive_feature_metadata(stream: TokenStream) -> TokenStream {
75	run(stream, feature_metadata::derive)
76}
77
78#[proc_macro_derive(NodeWithMetadata, attributes(metadata))]
79pub fn derive_node_with_metadata(stream: TokenStream) -> TokenStream {
80	run(stream, node_with_metadata::derive)
81}
82
83#[proc_macro_derive(ToCSSFeature, attributes(css_feature))]
84pub fn derive_css_feature(stream: TokenStream) -> TokenStream {
85	run(stream, css_feature::derive)
86}
87
88#[proc_macro_derive(DeclarationMetadata, attributes(declaration_metadata))]
89pub fn derive_declaration_metadata(stream: TokenStream) -> TokenStream {
90	run(stream, declaration_metadata::derive)
91}
92
93#[proc_macro_derive(SemanticEq, attributes(semantic_eq))]
94pub fn derive_semantic_eq(stream: TokenStream) -> TokenStream {
95	run(stream, semantic_eq::derive)
96}
97
98#[proc_macro_attribute]
99pub fn visitor(_attr: TokenStream, item: TokenStream) -> TokenStream {
100	let item = syn::parse_macro_input!(item as syn::ItemImpl);
101	visitor::expand(item).unwrap_or_else(|e| e.into_compile_error()).into()
102}