#![allow(clippy::type_complexity)]
use alloc::vec;
use alloc::vec::Vec;
use core::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
}