1use std::fmt;
5
6use crate::parse::Syntax;
7use crate::{Scope, ScopeParseError};
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
11pub enum IdentityAttr {
12 Handle,
14 Any,
16}
17
18impl IdentityAttr {
19 fn parse(value: &str) -> Result<Self, ScopeParseError> {
20 match value {
21 "handle" => Ok(Self::Handle),
22 "*" => Ok(Self::Any),
23 other => Err(ScopeParseError::UnknownAttribute(other.to_owned())),
24 }
25 }
26
27 pub(crate) fn includes(self, other: Self) -> bool {
29 self == other || self == Self::Any
30 }
31}
32
33impl fmt::Display for IdentityAttr {
34 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
35 f.write_str(match self {
36 Self::Handle => "handle",
37 Self::Any => "*",
38 })
39 }
40}
41
42pub(crate) fn read(atom: &str, syntax: &mut Syntax<'_>) -> Result<Scope, ScopeParseError> {
44 let attr = syntax
45 .single("attr", true)
46 .filter(|attr| !attr.is_empty())
47 .ok_or_else(|| ScopeParseError::MissingValue(atom.to_owned()))?;
48 Ok(Scope::Identity {
49 attr: IdentityAttr::parse(&attr)?,
50 })
51}