use std::collections::BTreeMap;
use std::io::Write;
use std::str;
use quick_xml::events::{BytesEnd, BytesStart, BytesText, Event};
use quick_xml::Writer;
use crate::error::XmlError;
use crate::toxml::ToXml;
pub(crate) mod util;
pub type ExtensionMap = BTreeMap<String, BTreeMap<String, Vec<Extension>>>;
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[derive(Debug, Default, Clone, PartialEq)]
#[cfg_attr(feature = "builders", derive(Builder))]
#[cfg_attr(
feature = "builders",
builder(
setter(into),
default,
build_fn(name = "build_impl", private, error = "std::convert::Infallible")
)
)]
pub struct Extension {
pub name: String,
pub value: Option<String>,
#[cfg_attr(feature = "builders", builder(setter(each = "attr")))]
pub attrs: BTreeMap<String, String>,
#[cfg_attr(feature = "builders", builder(setter(each = "child")))]
pub children: BTreeMap<String, Vec<Extension>>,
}
impl Extension {
pub fn name(&self) -> &str {
self.name.as_str()
}
pub fn set_name<V>(&mut self, name: V)
where
V: Into<String>,
{
self.name = name.into();
}
pub fn value(&self) -> Option<&str> {
self.value.as_deref()
}
pub fn set_value<V>(&mut self, value: V)
where
V: Into<Option<String>>,
{
self.value = value.into();
}
pub fn attrs(&self) -> &BTreeMap<String, String> {
&self.attrs
}
pub fn set_attrs<V>(&mut self, attrs: V)
where
V: Into<BTreeMap<String, String>>,
{
self.attrs = attrs.into();
}
pub fn children(&self) -> &BTreeMap<String, Vec<Extension>> {
&self.children
}
pub fn set_children<V>(&mut self, children: V)
where
V: Into<BTreeMap<String, Vec<Extension>>>,
{
self.children = children.into();
}
}
impl ToXml for Extension {
fn to_xml<W: Write>(&self, writer: &mut Writer<W>) -> Result<(), XmlError> {
let mut element = BytesStart::new(&self.name);
element.extend_attributes(self.attrs.iter().map(|a| (a.0.as_bytes(), a.1.as_bytes())));
writer
.write_event(Event::Start(element))
.map_err(XmlError::new)?;
if let Some(value) = self.value.as_ref() {
writer
.write_event(Event::Text(BytesText::new(value)))
.map_err(XmlError::new)?;
}
for extension in self.children.values().flatten() {
extension.to_xml(writer)?;
}
writer
.write_event(Event::End(BytesEnd::new(&self.name)))
.map_err(XmlError::new)?;
Ok(())
}
}
#[cfg(feature = "builders")]
impl ExtensionBuilder {
pub fn build(&self) -> Extension {
self.build_impl().unwrap()
}
}