use std::borrow::Cow;
use std::str::Utf8Error;
use quick_xml::events::BytesStart;
use crate::attribute::{Attribute, Error as AttributeError, Iter as AttributeIter};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TagStart<'a>
{
inner: BytesStart<'a>,
}
impl<'a> TagStart<'a>
{
pub fn new(name: impl Into<Cow<'a, str>>) -> Self
{
Self {
inner: BytesStart::new(name),
}
}
#[must_use]
pub fn with_attributes<Attrs>(mut self, attrs: Attrs) -> Self
where
Attrs: IntoIterator<Item = Attribute<'a>>,
{
self.inner = self
.inner
.with_attributes(attrs.into_iter().map(Attribute::into_inner));
self
}
pub fn name(&self) -> Result<&str, TagStartError>
{
std::str::from_utf8(self.name_bytes()).map_err(TagStartError::NameNotUTF8)
}
#[must_use]
pub fn name_bytes(&self) -> &[u8]
{
let name_length = self.inner.name().as_ref().len();
&self.inner.as_ref()[..name_length]
}
#[must_use]
pub fn attributes(&'a self) -> AttributeIter<'a>
{
AttributeIter::new(self.inner.attributes())
}
pub fn get_attribute(
&self,
attr_name: &str,
) -> Result<Option<Attribute>, TagStartError>
{
for attr_result in self.inner.attributes().with_checks(false) {
let attr = attr_result.map_err(AttributeError::from)?;
if attr.key.as_ref() == attr_name.as_bytes() {
return Ok(Some(Attribute::from_inner(attr)));
}
}
Ok(None)
}
}
impl<'a> TagStart<'a>
{
pub(crate) fn from_inner(inner: BytesStart<'a>) -> Self
{
Self { inner }
}
}
#[derive(Debug, thiserror::Error)]
pub enum TagStartError
{
#[error("Invalid attribute")]
InvalidAttribute(#[from] AttributeError),
#[error("Name is not valid UTF-8")]
NameNotUTF8(#[source] Utf8Error),
}