#![allow(clippy::type_complexity)]
use std::fmt::Debug;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Attribute<NS, ATT, VAL>
where
NS: PartialEq + Clone + Debug,
ATT: PartialEq + Clone + Debug,
VAL: PartialEq + Clone + Debug,
{
pub namespace: Option<NS>,
pub name: ATT,
pub value: Vec<VAL>,
}
impl<NS, ATT, VAL> Attribute<NS, ATT, VAL>
where
NS: PartialEq + Clone + Debug,
ATT: PartialEq + Clone + Debug,
VAL: PartialEq + Clone + Debug,
{
pub fn new(namespace: Option<NS>, name: ATT, value: VAL) -> Self {
Attribute {
name,
value: vec![value],
namespace,
}
}
pub fn with_multiple_values(
namespace: Option<NS>,
name: ATT,
value: impl IntoIterator<Item = VAL>,
) -> Self {
Attribute {
name,
value: value.into_iter().collect(),
namespace,
}
}
pub fn name(&self) -> &ATT {
&self.name
}
pub fn value(&self) -> &[VAL] {
&self.value
}
pub fn namespace(&self) -> Option<&NS> {
self.namespace.as_ref()
}
}
#[inline]
pub fn attr<NS, ATT, VAL>(name: ATT, value: VAL) -> Attribute<NS, ATT, VAL>
where
NS: PartialEq + Clone + Debug,
ATT: PartialEq + Clone + Debug,
VAL: PartialEq + Clone + Debug,
{
attr_ns(None, name, value)
}
#[inline]
pub fn attr_ns<NS, ATT, VAL>(
namespace: Option<NS>,
name: ATT,
value: VAL,
) -> Attribute<NS, ATT, VAL>
where
NS: PartialEq + Clone + Debug,
ATT: PartialEq + Clone + Debug,
VAL: PartialEq + Clone + Debug,
{
Attribute::new(namespace, name, value)
}
#[doc(hidden)]
pub fn merge_attributes_of_same_name<NS, ATT, VAL>(
attributes: &[&Attribute<NS, ATT, VAL>],
) -> Vec<Attribute<NS, ATT, VAL>>
where
NS: PartialEq + Clone + Debug,
ATT: PartialEq + Clone + Debug,
VAL: PartialEq + Clone + Debug,
{
let mut merged: Vec<Attribute<NS, ATT, VAL>> = vec![];
for att in attributes {
if let Some(existing) =
merged.iter_mut().find(|m_att| m_att.name == att.name)
{
existing.value.extend(att.value.clone());
} else {
merged.push(Attribute {
namespace: None,
name: att.name.clone(),
value: att.value.clone(),
});
}
}
merged
}
#[doc(hidden)]
pub fn group_attributes_per_name<NS, ATT, VAL>(
attributes: &[Attribute<NS, ATT, VAL>],
) -> Vec<(&ATT, Vec<&Attribute<NS, ATT, VAL>>)>
where
NS: PartialEq + Clone + Debug,
ATT: PartialEq + Clone + Debug,
VAL: PartialEq + Clone + Debug,
{
let mut grouped: Vec<(&ATT, Vec<&Attribute<NS, ATT, VAL>>)> = vec![];
for attr in attributes {
if let Some(existing) = grouped
.iter_mut()
.find(|(g_att, _)| **g_att == attr.name)
.map(|(_, attr)| attr)
{
existing.push(attr);
} else {
grouped.push((&attr.name, vec![attr]))
}
}
grouped
}