[go: up one dir, main page]

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}