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(Debug, TryClone, PartialEq, Eq, ToTokens, OptionSpanned)]
44#[non_exhaustive]
45pub enum Visibility {
46    /// An inherited visibility level, this usually means private.
47    Inherited,
48    /// An unrestricted public visibility level: `pub`.
49    Public(T![pub]),
50    /// Crate visibility `pub(crate)`.
51    Crate(VisibilityRestrict<T![crate]>),
52    /// Super visibility `pub(super)`.
53    Super(VisibilityRestrict<T![super]>),
54    /// Self visibility `pub(self)`.
55    SelfValue(VisibilityRestrict<T![self]>),
56    /// In visibility `pub(in path)`.
57    In(VisibilityRestrict<VisibilityIn>),
58}
59
60impl Visibility {
61    /// Return `true` if it is the `Inherited` variant
62    pub const fn is_inherited(&self) -> bool {
63        matches!(self, Visibility::Inherited)
64    }
65
66    /// Return `true` if the module is public.
67    pub const fn is_public(&self) -> bool {
68        matches!(self, Visibility::Public(..))
69    }
70}
71
72impl Default for Visibility {
73    fn default() -> Self {
74        Self::Inherited
75    }
76}
77
78impl Parse for Visibility {
79    fn parse(parser: &mut Parser<'_>) -> Result<Self> {
80        let pub_token = match parser.parse::<Option<T![pub]>>()? {
81            Some(pub_token) => pub_token,
82            None => return Ok(Self::Inherited),
83        };
84
85        let open = match parser.parse::<Option<ast::OpenParen>>()? {
86            Some(open) => open,
87            None => return Ok(Self::Public(pub_token)),
88        };
89
90        Ok(match parser.nth(0)? {
91            K![in] => Self::In(VisibilityRestrict {
92                pub_token,
93                open,
94                restriction: VisibilityIn {
95                    in_token: parser.parse()?,
96                    path: parser.parse()?,
97                },
98                close: parser.parse()?,
99            }),
100            K![super] => Self::Super(VisibilityRestrict {
101                pub_token,
102                open,
103                restriction: parser.parse()?,
104                close: parser.parse()?,
105            }),
106            K![self] => Self::SelfValue(VisibilityRestrict {
107                pub_token,
108                open,
109                restriction: parser.parse()?,
110                close: parser.parse()?,
111            }),
112            _ => Self::Crate(VisibilityRestrict {
113                pub_token,
114                open,
115                restriction: parser.parse()?,
116                close: parser.parse()?,
117            }),
118        })
119    }
120}
121
122/// A `in path` restriction to visibility.
123#[derive(Debug, TryClone, PartialEq, Eq, ToTokens, Spanned)]
124#[non_exhaustive]
125pub struct VisibilityIn {
126    /// The `in` keyword.
127    pub in_token: T![in],
128    /// The path the restriction applies to.
129    pub path: ast::Path,
130}
131
132/// A restriction to visibility.
133#[derive(Debug, TryClone, PartialEq, Eq, ToTokens, Spanned)]
134#[non_exhaustive]
135#[try_clone(bound = {T: TryClone})]
136pub struct VisibilityRestrict<T> {
137    /// `pub` keyword.
138    pub pub_token: ast::generated::Pub,
139    /// Opening paren `(`.
140    pub open: ast::OpenParen,
141    /// The restriction.
142    pub restriction: T,
143    /// Closing paren `)`.
144    pub close: ast::CloseParen,
145}