use derive_more::{Display, IsVariant, TryUnwrap, Unwrap};
use smol_str::SmolStr;
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Display, IsVariant, Unwrap, TryUnwrap)]
#[display("{}", self.as_str())]
#[unwrap(ref, ref_mut)]
#[try_unwrap(ref, ref_mut)]
#[non_exhaustive]
#[cfg_attr(
feature = "quickcheck",
derive(::quickcheck_richderive::Arbitrary),
quickcheck(arbitrary = "crate::quickcheck_helpers::strings::track_origin")
)]
pub enum TrackOrigin {
#[default]
Embedded,
Sidecar,
External,
Derived,
Other(SmolStr),
}
impl TrackOrigin {
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn as_str(&self) -> &str {
match self {
Self::Embedded => "embedded",
Self::Sidecar => "sidecar",
Self::External => "external",
Self::Derived => "derived",
Self::Other(s) => s.as_str(),
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn to_u32(&self) -> Option<u32> {
Some(match self {
Self::Embedded => 0,
Self::Sidecar => 1,
Self::External => 2,
Self::Derived => 3,
Self::Other(_) => return None,
})
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn from_u32(v: u32) -> Self {
match v {
0 => Self::Embedded,
1 => Self::Sidecar,
2 => Self::External,
3 => Self::Derived,
_ => Self::Embedded,
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn try_from_u32(v: u32) -> Option<Self> {
match v {
0 => Some(Self::Embedded),
1 => Some(Self::Sidecar),
2 => Some(Self::External),
3 => Some(Self::Derived),
_ => None,
}
}
pub fn other(slug: impl AsRef<str>) -> Self {
Self::Other(crate::parse::fold_owned(slug.as_ref()))
}
}
roster!(
TrackOrigin,
"track origin",
[Embedded, Sidecar, External, Derived],
escape: Other
);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, thiserror::Error)]
#[error("not a track-origin name")]
#[non_exhaustive]
pub struct ParseTrackOriginError;
impl core::str::FromStr for TrackOrigin {
type Err = core::convert::Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut buf = [0u8; crate::parse::FOLD_CAP];
let folded = crate::parse::fold(s, &mut buf).unwrap_or(s.as_bytes());
Ok(match folded {
b"embedded" => Self::Embedded,
b"sidecar" => Self::Sidecar,
b"external" => Self::External,
b"derived" => Self::Derived,
_ => Self::other(s),
})
}
}
#[cfg(test)]
mod tests;