visible/lib.rs
1//! Attributes to override the visibility of items.
2//!
3//! ## Example
4//!
5//! ```Rust
6//! #[visible::StructFields(pub(crate))]
7//! pub struct Test {
8//! pub a: i32,
9//! pub b: i64,
10//! }
11//! ```
12//!
13//! The struct `Test` will be rewritten as below:
14//!
15//! ```Rust
16//! pub struct Test {
17//! pub(crate) a: i32,
18//! pub(crate) b: i64,
19//! }
20//! ```
21
22use proc_macro::TokenStream;
23use quote::ToTokens;
24use syn::{parse_macro_input, Fields, Item, ItemStruct, Visibility};
25
26/// **Override**s the visibility of the annotated struct fields with the one given to
27/// this attribute:
28///
29/// ## Example
30///
31/// ```rust
32/// #[visible::StructFields(pub(crate))]
33/// pub struct Test {
34/// pub a: i32,
35/// pub b: i64,
36/// }
37/// ```
38#[allow(non_snake_case)]
39#[proc_macro_attribute]
40pub fn StructFields(attrs: TokenStream, input: TokenStream) -> TokenStream {
41 let visibility: Visibility = parse_macro_input!(attrs);
42 let mut input: Item = parse_macro_input!(input);
43
44 if let Item::Struct(ItemStruct { ref mut fields, .. }) = input {
45 match fields {
46 Fields::Named(fields) => {
47 for field in &mut fields.named {
48 field.vis = visibility.clone();
49 }
50 }
51 Fields::Unnamed(fields) => {
52 for field in &mut fields.unnamed {
53 field.vis = visibility.clone();
54 }
55 }
56 Fields::Unit => {}
57 }
58 }
59
60 input.into_token_stream().into()
61}