Skip to main content

mago_codex/
visibility.rs

1use serde::Deserialize;
2use serde::Serialize;
3
4use mago_syntax::ast::Modifier;
5
6/// Represents the visibility level of class members (properties, methods, constants) in PHP.
7#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Serialize, Deserialize, Default, PartialOrd, Ord)]
8#[repr(u8)]
9pub enum Visibility {
10    /// Represents `public` visibility. Accessible from anywhere.
11    /// This is the default visibility in PHP if none is specified.
12    #[default]
13    Public,
14    /// Represents `protected` visibility. Accessible only within the declaring class,
15    /// its parent classes, and inheriting classes.
16    Protected,
17    /// Represents `private` visibility. Accessible only within the declaring class.
18    Private,
19}
20
21impl Visibility {
22    /// Checks if the visibility level is `Public`.
23    #[inline]
24    #[must_use]
25    pub const fn is_public(&self) -> bool {
26        matches!(self, Visibility::Public)
27    }
28
29    /// Checks if the visibility level is `Protected`.
30    #[inline]
31    #[must_use]
32    pub const fn is_protected(&self) -> bool {
33        matches!(self, Visibility::Protected)
34    }
35
36    /// Checks if the visibility level is `Private`.
37    #[inline]
38    #[must_use]
39    pub const fn is_private(&self) -> bool {
40        matches!(self, Visibility::Private)
41    }
42
43    /// Returns the visibility level as a static string.
44    #[inline]
45    #[must_use]
46    pub const fn as_str(&self) -> &'static str {
47        match self {
48            Visibility::Public => "public",
49            Visibility::Protected => "protected",
50            Visibility::Private => "private",
51        }
52    }
53}
54
55/// Formats the visibility level as the corresponding lowercase PHP keyword.
56impl std::fmt::Display for Visibility {
57    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58        write!(f, "{}", self.as_str())
59    }
60}
61
62/// Attempts to convert an AST `Modifier` node into a `Visibility` level.
63impl TryFrom<&Modifier<'_>> for Visibility {
64    type Error = ();
65
66    fn try_from(value: &Modifier<'_>) -> Result<Self, Self::Error> {
67        match value {
68            Modifier::Public(_) | Modifier::PublicSet(_) => Ok(Visibility::Public),
69            Modifier::Protected(_) | Modifier::ProtectedSet(_) => Ok(Visibility::Protected),
70            Modifier::Private(_) | Modifier::PrivateSet(_) => Ok(Visibility::Private),
71            _ => Err(()),
72        }
73    }
74}