//! Tagged element. use std::borrow::Cow; use std::str::Utf8Error; use quick_xml::events::BytesStart; use crate::attribute::{Attribute, Error as AttributeError, Iter as AttributeIter}; /// The start tag of a tagged element. /// /// The `` in `Hello` #[derive(Debug, Clone, PartialEq, Eq)] pub struct TagStart<'a> { inner: BytesStart<'a>, } impl<'a> TagStart<'a> { /// Returns a new `TagStart`. pub fn new(name: impl Into>) -> Self { Self { inner: BytesStart::new(name), } } /// Returns `Self` with the specified attributes. #[must_use] pub fn with_attributes(mut self, attrs: Attrs) -> Self where Attrs: IntoIterator>, { self.inner = self .inner .with_attributes(attrs.into_iter().map(Attribute::into_inner)); self } /// Returns the name. /// /// # Errors /// Returns `Err` if the name is not valid UTF-8. pub fn name(&self) -> Result<&str, Utf8Error> { std::str::from_utf8(self.name_bytes()) } /// Returns the name as bytes. #[must_use] pub fn name_bytes(&self) -> &[u8] { let name_length = self.inner.name().as_ref().len(); &self.inner.as_ref()[..name_length] } /// Returns the tag attributes. #[must_use] pub fn attributes(&'a self) -> AttributeIter<'a> { AttributeIter::new(self.inner.attributes()) } /// Returns a attribute. /// /// # Errors /// Returns `Err` if a invalid attribute is found. pub fn get_attribute( &self, attr_name: &str, ) -> Result, 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) } } // Crate-local functions impl<'a> TagStart<'a> { pub(crate) fn from_inner(inner: BytesStart<'a>) -> Self { Self { inner } } } /// `TagStart` error. #[derive(Debug, thiserror::Error)] pub enum TagStartError { /// Invalid attribute. #[error("Invalid attribute")] InvalidAttribute(#[from] AttributeError), }