use crate::value::keys::Keys;
use bstr::ByteSlice;
#[derive(Clone, PartialEq)]
pub(crate) struct Label(Vec<u8>);
impl core::fmt::Debug for Label {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str(&self.to_string())
}
}
impl core::fmt::Display for Label {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str(&String::from_utf8_lossy(&self.0))
}
}
#[cfg(test)]
impl<T: Into<Vec<u8>>> From<T> for Label {
fn from(value: T) -> Self {
Self(value.into())
}
}
impl Label {
pub(crate) fn new<T: Into<Vec<u8>>>(value: T) -> Option<Self> {
Some(Self(value.into()))
.filter(|l| !l.0.contains_str("::"))
.filter(|l| !l.as_name().is_empty())
}
pub(crate) fn as_name(&self) -> &[u8] {
match self.0.find_byte(b':') {
None => self.as_bytes(),
Some(_) if self.0.len() == 1 => &[],
Some(i) if i == self.0.len() - 1 => &self.0[..i],
Some(i) => match self.0[(i + 1)..].rfind_byte(b':') {
None => &self.0[(i + 1)..],
Some(j) => &self.0[(i + 1)..(i + 1 + j)],
},
}
}
pub(crate) fn as_keys(&self) -> Keys {
Keys::parse(self.as_name())
}
pub(crate) fn as_prefix(&self) -> Option<&[u8]> {
self.0.find_byte(b':').and_then(|i| self.0.get(..i))
}
pub(crate) fn as_suffix(&self) -> Option<&[u8]> {
self.0.rfind_byte(b':').and_then(|i| self.0.get((i + 1)..))
}
pub(crate) fn as_bytes(&self) -> &[u8] {
&self.0
}
}
#[cfg(test)]
mod test {
use crate::lang::label::Label;
use crate::value::keys::Keys;
#[test]
fn test() {
assert_eq!(Label::new(""), None);
assert_eq!(Label::new("::"), None);
assert_eq!(Label::new("a").unwrap().as_name(), b"a");
assert_eq!(Label::new("a:").unwrap().as_name(), b"a");
assert_eq!(Label::new("a:").unwrap().as_prefix().unwrap(), b"a");
assert_eq!(Label::new(":a").unwrap().as_name(), b"a");
assert_eq!(Label::new("fn:a").unwrap().as_name(), b"a");
assert_eq!(Label::new("abc:").unwrap().as_name(), b"abc");
assert_eq!(Label::new("a:foo").unwrap().as_name(), b"foo");
assert_eq!(Label::new("a:b:c").unwrap().as_prefix().unwrap(), b"a");
assert_eq!(Label::new("a:b:c").unwrap().as_name(), b"b");
assert_eq!(Label::new("a:b:c").unwrap().as_suffix().unwrap(), b"c");
assert_eq!(Label::new("a").unwrap().as_keys(), Keys::from("a"));
assert_eq!(Label::new("a:b").unwrap().as_keys(), Keys::from("b"));
assert_eq!(Label::new("a:b:c").unwrap().as_keys(), Keys::from("b"));
assert_eq!(Label::new(":c").unwrap().as_keys(), Keys::from("c"));
}
}