use std::{
borrow::Cow,
fmt::{self, Display, Formatter},
};
use compose_spec_macros::{DeserializeTryFromString, SerializeDisplay};
use crate::{impl_from_str, Identifier, InvalidIdentifierError};
#[derive(SerializeDisplay, DeserializeTryFromString, Debug, Clone, PartialEq, Eq)]
pub enum Network {
Identifier(Identifier),
None,
}
impl Network {
const NONE: &'static str = "none";
pub fn parse<T>(network: T) -> Result<Self, T::Error>
where
T: AsRef<str> + TryInto<Identifier>,
{
if network.as_ref() == Self::NONE {
Ok(Self::None)
} else {
network.try_into().map(Self::Identifier)
}
}
#[must_use]
pub fn as_str(&self) -> &str {
match self {
Self::Identifier(network) => network.as_str(),
Self::None => Self::NONE,
}
}
#[must_use]
pub const fn is_none(&self) -> bool {
matches!(self, Self::None)
}
#[must_use]
pub fn into_option(self) -> Option<Identifier> {
match self {
Self::Identifier(network) => Some(network),
Self::None => None,
}
}
}
impl_from_str!(Network => InvalidIdentifierError);
impl AsRef<str> for Network {
fn as_ref(&self) -> &str {
self.as_str()
}
}
impl Display for Network {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
f.write_str(self.as_str())
}
}
impl From<Network> for Cow<'static, str> {
fn from(value: Network) -> Self {
match value {
Network::Identifier(network) => Self::Owned(network.into()),
Network::None => Self::Borrowed(Network::NONE),
}
}
}
impl From<Network> for String {
fn from(value: Network) -> Self {
Cow::from(value).into_owned()
}
}