rune/ast/
vis.rs

1use crate::ast::prelude::*;
2
3#[test]
4#[cfg(not(miri))]
5fn ast_parse() {
6    assert!(matches! {
7        rt::<ast::Visibility>("pub"),
8        ast::Visibility::Public(_)
9    });
10
11    assert!(matches! {
12        rt::<ast::Visibility>("pub (in a::b::c)"),
13        ast::Visibility::In(_)
14    });
15
16    assert!(matches! {
17        rt::<ast::Visibility>("pub(in crate::x::y::z)"),
18        ast::Visibility::In(_)
19    });
20
21    assert!(matches! {
22        rt::<ast::Visibility>("pub(super)"),
23        ast::Visibility::Super(_)
24    });
25
26    assert!(matches! {
27        rt::<ast::Visibility>("pub(crate)"),
28        ast::Visibility::Crate(_)
29    });
30
31    assert!(matches! {
32        rt::<ast::Visibility>("pub(self)"),
33        ast::Visibility::SelfValue(_)
34    });
35}
36
37/// Visibility level restricted to some path.
38///
39/// * `pub(self)`.
40/// * `pub(super)`.
41/// * `pub(crate)`.
42/// * `pub(in some::module)`.
43#[derive(Default, Debug, TryClone, PartialEq, Eq, ToTokens, OptionSpanned)]
44#[non_exhaustive]
45pub enum Visibility {
46    /// An inherited visibility level, this usually means private.
47    #[default]
48    Inherited,
49    /// An unrestricted public visibility level: `pub`.
50    Public(T![pub]),
51    /// Crate visibility `pub(crate)`.
52    Crate(VisibilityRestrict<T![crate]>),
53    /// Super visibility `pub(super)`.
54    Super(VisibilityRestrict<T![super]>),
55    /// Self visibility `pub(self)`.
56    SelfValue(VisibilityRestrict<T![self]>),
57    /// In visibility `pub(in path)`.
58    In(VisibilityRestrict<VisibilityIn>),
59}
60
61impl Visibility {
62    /// Return `true` if it is the `Inherited` variant
63    pub const fn is_inherited(&self) -> bool {
64        matches!(self, Visibility::Inherited)
65    }
66
67    /// Return `true` if the module is public.
68    pub const fn is_public(&self) -> bool {
69        matches!(self, Visibility::Public(..))
70    }
71}
72
73impl Parse for Visibility {
74    fn parse(parser: &mut Parser<'_>) -> Result<Self> {
75        let pub_token = match parser.parse::<Option<T![pub]>>()? {
76            Some(pub_token) => pub_token,
77            None => return Ok(Self::Inherited),
78        };
79
80        let open = match parser.parse::<Option<ast::OpenParen>>()? {
81            Some(open) => open,
82            None => return Ok(Self::Public(pub_token)),
83        };
84
85        Ok(match parser.nth(0)? {
86            K![in] => Self::In(VisibilityRestrict {
87                pub_token,
88                open,
89                restriction: VisibilityIn {
90                    in_token: parser.parse()?,
91                    path: parser.parse()?,
92                },
93                close: parser.parse()?,
94            }),
95            K![super] => Self::Super(VisibilityRestrict {
96                pub_token,
97                open,
98                restriction: parser.parse()?,
99                close: parser.parse()?,
100            }),
101            K![self] => Self::SelfValue(VisibilityRestrict {
102                pub_token,
103                open,
104                restriction: parser.parse()?,
105                close: parser.parse()?,
106            }),
107            _ => Self::Crate(VisibilityRestrict {
108                pub_token,
109                open,
110                restriction: parser.parse()?,
111                close: parser.parse()?,
112            }),
113        })
114    }
115}
116
117/// A `in path` restriction to visibility.
118#[derive(Debug, TryClone, PartialEq, Eq, ToTokens, Spanned)]
119#[non_exhaustive]
120pub struct VisibilityIn {
121    /// The `in` keyword.
122    pub in_token: T![in],
123    /// The path the restriction applies to.
124    pub path: ast::Path,
125}
126
127/// A restriction to visibility.
128#[derive(Debug, TryClone, PartialEq, Eq, ToTokens, Spanned)]
129#[non_exhaustive]
130#[try_clone(bound = {T: TryClone})]
131pub struct VisibilityRestrict<T> {
132    /// `pub` keyword.
133    pub pub_token: ast::generated::Pub,
134    /// Opening paren `(`.
135    pub open: ast::OpenParen,
136    /// The restriction.
137    pub restriction: T,
138    /// Closing paren `)`.
139    pub close: ast::CloseParen,
140}