local_type_alias/lib.rs
1//! `local-type-aliases` allows for the creation of scoped type and trait
2//! aliases in an item.
3//!
4//! ## Examples
5//!
6//! ```rust
7//! # use local_type_alias::local_alias;
8//! #
9//! # use std::ops::Add;
10//! #
11//! #[local_alias]
12//! #[alias(type X = i32)]
13//! struct MyType<T>
14//! where
15//! X: for<'a> Add<&'a T>,
16//! {
17//! value: T,
18//! }
19//! ```
20//!
21//! ```rust
22//! # use local_type_alias::local_alias;
23//! #
24//! # struct MyType<T>(T);
25//! #
26//! #[local_alias]
27//! #[alias(
28//! type X = [u8; 4],
29//! type Y = *mut X,
30//! type Z = fn(X) -> Y,
31//! trait A = PartialEq<fn([u8; 4]) -> *mut X>,
32//! )]
33//! impl<T> MyType<T>
34//! where
35//! Z: A,
36//! {
37//! // ...
38//! }
39//! ```
40
41mod substitute;
42
43use quote::ToTokens as _;
44
45use syn::parse_macro_input;
46use syn::visit_mut::VisitMut as _;
47use syn::Item;
48
49/// Local type aliases.
50///
51/// See the [crate documentation][crate] for details.
52#[proc_macro_attribute]
53pub fn local_alias(
54 args: proc_macro::TokenStream,
55 item: proc_macro::TokenStream,
56) -> proc_macro::TokenStream {
57 let mut input = parse_macro_input!(item as Item);
58
59 let mut in_macros = false;
60 let options_parser = syn::meta::parser(|meta| {
61 if meta.path.is_ident("macros") {
62 in_macros = true;
63 Ok(())
64 } else {
65 Err(meta.error("unsupported local alias option"))
66 }
67 });
68
69 parse_macro_input!(args with options_parser);
70
71 let mut visitor = match substitute::Visitor::new(in_macros, &mut input) {
72 Ok(visitor) => visitor,
73 Err(error) => return error.into_compile_error().into(),
74 };
75
76 visitor.visit_item_mut(&mut input);
77
78 input.into_token_stream().into()
79}