use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
#[derive(Default)]
pub enum Visibility {
#[default]
Public,
Private,
}
impl Visibility {
#[must_use]
pub const fn all() -> &'static [Self] {
&[Self::Public, Self::Private]
}
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::Public => "public",
Self::Private => "private",
}
}
#[must_use]
pub fn parse(s: &str) -> Option<Self> {
match s.to_lowercase().as_str() {
"public" | "pub" | "exported" => Some(Self::Public),
"private" | "priv" | "internal" => Some(Self::Private),
_ => None,
}
}
#[must_use]
pub const fn is_public(self) -> bool {
matches!(self, Self::Public)
}
#[must_use]
pub const fn is_private(self) -> bool {
matches!(self, Self::Private)
}
}
impl fmt::Display for Visibility {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_as_str() {
assert_eq!(Visibility::Public.as_str(), "public");
assert_eq!(Visibility::Private.as_str(), "private");
}
#[test]
fn test_parse() {
assert_eq!(Visibility::parse("public"), Some(Visibility::Public));
assert_eq!(Visibility::parse("PRIVATE"), Some(Visibility::Private));
assert_eq!(Visibility::parse("pub"), Some(Visibility::Public));
assert_eq!(Visibility::parse("internal"), Some(Visibility::Private));
assert_eq!(Visibility::parse("unknown"), None);
}
#[test]
fn test_display() {
assert_eq!(format!("{}", Visibility::Public), "public");
assert_eq!(format!("{}", Visibility::Private), "private");
}
#[test]
fn test_serde_roundtrip() {
for vis in Visibility::all() {
let json = serde_json::to_string(vis).unwrap();
let deserialized: Visibility = serde_json::from_str(&json).unwrap();
assert_eq!(*vis, deserialized);
}
}
#[test]
fn test_classification() {
assert!(Visibility::Public.is_public());
assert!(!Visibility::Public.is_private());
assert!(Visibility::Private.is_private());
assert!(!Visibility::Private.is_public());
}
}