-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathlib.rs
84 lines (78 loc) · 2.77 KB
/
lib.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#![forbid(unsafe_code)]
#![allow(nonstandard_style, unused_imports)]
#![cfg_attr(feature = "nightly",
cfg_attr(all(), doc = include_str!("../README.md")),
)]
extern crate proc_macro;
use ::proc_macro::TokenStream;
use ::proc_macro2::{Span, TokenStream as TokenStream2};
use ::quote::{
quote,
quote_spanned,
ToTokens,
};
use ::syn::{*,
parse::Parse,
Result,
};
/// **Override**s the visibility of the annotated item with the one given to
/// this attribute:
///
/// ## Example
///
/// ```rust
/// mod module {
/// #[visibility::make(pub)]
/// fn foo () {}
/// }
///
/// module::foo();
/// ```
///
/// ## To be used in conjunction with `#[cfg_attr]`
///
/// That's where this attribute really shines: it is not possible to
/// conditionally modify the visibility of an item, but it is possible to
/// conditionally apply an attribute. If the attribute then modifies the
/// visibility of the decorated item, we have achieved our goal:
///
/// ```rust
/// mod module {
/// #[cfg_attr(all(/* feature = "integration-tests" */),
/// visibility::make(pub),
/// )]
/// fn foo () {}
/// }
///
/// module::foo();
/// ```
#[proc_macro_attribute] pub
fn make (attrs: TokenStream, input: TokenStream)
-> TokenStream
{
let visibility: Visibility = parse_macro_input!(attrs);
let mut input: Item = parse_macro_input!(input);
match input {
| Item::Const(ItemConst { ref mut vis, .. }) => *vis = visibility,
| Item::Enum(ItemEnum { ref mut vis, .. }) => *vis = visibility,
| Item::ExternCrate(ItemExternCrate { ref mut vis, .. }) => *vis = visibility,
| Item::Fn(ItemFn { ref mut vis, .. }) => *vis = visibility,
// | Item::ForeignMod(ItemForeignMod { ref mut vis, .. }) => *vis = visibility,
// | Item::Impl(ItemImpl { ref mut vis, .. }) => *vis = visibility,
// | Item::Macro(ItemMacro { ref mut vis, .. }) => *vis = visibility,
| Item::Mod(ItemMod { ref mut vis, .. }) => *vis = visibility,
| Item::Static(ItemStatic { ref mut vis, .. }) => *vis = visibility,
| Item::Struct(ItemStruct { ref mut vis, .. }) => *vis = visibility,
| Item::Trait(ItemTrait { ref mut vis, .. }) => *vis = visibility,
| Item::TraitAlias(ItemTraitAlias { ref mut vis, .. }) => *vis = visibility,
| Item::Type(ItemType { ref mut vis, .. }) => *vis = visibility,
| Item::Union(ItemUnion { ref mut vis, .. }) => *vis = visibility,
| Item::Use(ItemUse { ref mut vis, .. }) => *vis = visibility,
// | Item::Verbatim(TokenStream { ref mut vis, .. }) => *vis = visibility,
| _ => return Error::new_spanned(
&input,
"Cannot override the `#[visibility]` of this item",
).to_compile_error().into(),
}
input.into_token_stream().into()
}