blob: ea45ee9b55835647566f698223173eaed5c0bf8f [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use {
crate::instanced_abs_moniker::InstancedAbsoluteMoniker,
core::cmp::Ord,
moniker::{AbsoluteMonikerBase, MonikerError},
std::fmt,
};
/// One of:
/// - An instanced absolute moniker
/// - A marker representing component manager's realm
#[derive(Eq, Ord, PartialOrd, PartialEq, Debug, Clone, Hash)]
pub enum InstancedExtendedMoniker {
ComponentInstance(InstancedAbsoluteMoniker),
ComponentManager,
}
/// The string representation of InstancedExtendedMoniker::ComponentManager
const EXTENDED_MONIKER_COMPONENT_MANAGER_STR: &'static str = "<component_manager>";
impl InstancedExtendedMoniker {
pub fn parse_str(rep: &str) -> Result<Self, MonikerError> {
if rep == EXTENDED_MONIKER_COMPONENT_MANAGER_STR {
Ok(InstancedExtendedMoniker::ComponentManager)
} else {
Ok(InstancedExtendedMoniker::ComponentInstance(InstancedAbsoluteMoniker::parse_str(
rep,
)?))
}
}
pub fn unwrap_instance_moniker_or<E: std::error::Error>(
&self,
error: E,
) -> Result<&InstancedAbsoluteMoniker, E> {
match self {
Self::ComponentManager => Err(error),
Self::ComponentInstance(moniker) => Ok(moniker),
}
}
pub fn contains_in_realm(&self, other: &InstancedExtendedMoniker) -> bool {
match (self, other) {
(Self::ComponentManager, _) => true,
(Self::ComponentInstance(_), Self::ComponentManager) => false,
(Self::ComponentInstance(a), Self::ComponentInstance(b)) => a.contains_in_realm(b),
}
}
}
impl fmt::Display for InstancedExtendedMoniker {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::ComponentInstance(m) => {
write!(f, "{}", m)?;
}
Self::ComponentManager => {
write!(f, "{}", EXTENDED_MONIKER_COMPONENT_MANAGER_STR)?;
}
}
Ok(())
}
}
impl From<InstancedAbsoluteMoniker> for InstancedExtendedMoniker {
fn from(m: InstancedAbsoluteMoniker) -> Self {
Self::ComponentInstance(m)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn instanced_extended_monikers_parse() {
assert_eq!(
InstancedExtendedMoniker::parse_str(EXTENDED_MONIKER_COMPONENT_MANAGER_STR).unwrap(),
InstancedExtendedMoniker::ComponentManager
);
assert_eq!(
InstancedExtendedMoniker::parse_str("/foo:0/bar:0").unwrap(),
InstancedExtendedMoniker::ComponentInstance(
InstancedAbsoluteMoniker::parse_str("/foo:0/bar:0").unwrap()
)
);
assert!(InstancedExtendedMoniker::parse_str("").is_err(), "cannot be empty");
assert!(InstancedExtendedMoniker::parse_str("foo:0/bar:0").is_err(), "must start with /");
}
#[test]
fn to_string_functions() {
let cm_moniker =
InstancedExtendedMoniker::parse_str(EXTENDED_MONIKER_COMPONENT_MANAGER_STR).unwrap();
let foobar_moniker = InstancedExtendedMoniker::parse_str("/foo:0/bar:0").unwrap();
let empty_moniker = InstancedExtendedMoniker::parse_str("/").unwrap();
assert_eq!(format!("{}", cm_moniker), EXTENDED_MONIKER_COMPONENT_MANAGER_STR.to_string());
assert_eq!(cm_moniker.to_string(), EXTENDED_MONIKER_COMPONENT_MANAGER_STR.to_string());
assert_eq!(format!("{}", foobar_moniker), "/foo:0/bar:0".to_string());
assert_eq!(format!("{}", empty_moniker), "/".to_string());
}
}