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}