use crate::libyml::safe_cstr;
use memchr::memchr;
use std::{
fmt::{self, Debug, Display},
ops::Deref,
};
#[derive(Clone, Copy, Debug, Hash, Ord, PartialOrd, Eq, PartialEq)]
pub struct TagFormatError;
impl Display for TagFormatError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Error occurred while formatting tag")
}
}
impl std::error::Error for TagFormatError {}
#[derive(Ord, PartialOrd, Eq, PartialEq, Clone, Hash)]
pub struct Tag(pub(in crate::libyml) Box<[u8]>);
impl Tag {
pub const NULL: &'static str = "tag:yaml.org,2002:null";
pub const BOOL: &'static str = "tag:yaml.org,2002:bool";
pub const INT: &'static str = "tag:yaml.org,2002:int";
pub const FLOAT: &'static str = "tag:yaml.org,2002:float";
pub fn starts_with(
&self,
prefix: &str,
) -> Result<bool, TagFormatError> {
if prefix.len() > self.0.len() {
Err(TagFormatError)
} else {
let prefix_bytes = prefix.as_bytes();
let tag_bytes = &self.0[..prefix_bytes.len()];
Ok(tag_bytes == prefix_bytes)
}
}
pub fn new(tag_str: &str) -> Tag {
Tag(Box::from(tag_str.as_bytes()))
}
}
impl PartialEq<str> for Tag {
fn eq(&self, other: &str) -> bool {
self.0 == other.as_bytes().into()
}
}
impl PartialEq<&str> for Tag {
fn eq(&self, other: &&str) -> bool {
self.0 == other.as_bytes().into()
}
}
impl Deref for Tag {
type Target = [u8];
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl Debug for Tag {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(null_pos) = memchr(b'\0', &self.0) {
safe_cstr::debug_lossy(&self.0[..null_pos], formatter)
} else {
safe_cstr::debug_lossy(&self.0, formatter)
}
}
}