use std::mem;
use std::iter::{Filter, Map};
use std::slice::{Iter, IterMut};
use {
Attribute,
AttributeNameRef,
AttributeId,
AttributeValue
};
pub type SvgAttrFilter<'a> = Filter<Iter<'a, Attribute>, fn(&&Attribute) -> bool>;
pub type SvgAttrFilterMut<'a> = Filter<IterMut<'a, Attribute>, fn(&&mut Attribute) -> bool>;
pub struct Attributes(Vec<Attribute>);
impl Attributes {
#[inline]
pub fn new() -> Attributes {
Attributes(Vec::new())
}
#[inline]
pub fn get<'a, N>(&self, name: N) -> Option<&Attribute>
where AttributeNameRef<'a>: From<N>
{
let name = AttributeNameRef::from(name);
for v in &self.0 {
if v.name.into_ref() == name {
return Some(v);
}
}
None
}
#[inline]
pub fn get_mut<'a, N>(&mut self, name: N) -> Option<&mut Attribute>
where AttributeNameRef<'a>: From<N>
{
let name = AttributeNameRef::from(name);
for v in &mut self.0 {
if v.name.into_ref() == name {
return Some(v);
}
}
None
}
#[inline]
pub fn get_value<'a, N>(&self, name: N) -> Option<&AttributeValue>
where AttributeNameRef<'a>: From<N>
{
let name = AttributeNameRef::from(name);
for v in &self.0 {
if v.name.into_ref() == name {
return Some(&v.value);
}
}
None
}
#[inline]
pub fn get_value_mut<'a, N>(&mut self, name: N) -> Option<&mut AttributeValue>
where AttributeNameRef<'a>: From<N>
{
let name = AttributeNameRef::from(name);
for v in &mut self.0 {
if v.name.into_ref() == name {
return Some(&mut v.value);
}
}
None
}
pub fn insert(&mut self, attr: Attribute) {
if self.0.capacity() == 0 {
self.0.reserve(16);
}
let idx = self.0.iter().position(|x| x.name == attr.name);
match idx {
Some(i) => { mem::replace(&mut self.0[i], attr); }
None => self.0.push(attr),
}
}
pub fn insert_from<'a, N, T>(&mut self, name: N, value: T)
where AttributeNameRef<'a>: From<N>, N: Copy, AttributeValue: From<T>
{
self.insert(Attribute::new(name, value));
}
pub fn remove<'a, N>(&mut self, name: N)
where AttributeNameRef<'a>: From<N>
{
let name = AttributeNameRef::from(name);
let idx = self.0.iter().position(|x| x.name.into_ref() == name);
if let Some(i) = idx {
self.0.remove(i);
}
}
#[inline]
pub fn contains<'a, N>(&self, name: N) -> bool
where AttributeNameRef<'a>: From<N>
{
let name = AttributeNameRef::from(name);
self.0.iter().any(|a| a.name.into_ref() == name)
}
#[inline]
pub fn len(&self) -> usize {
self.0.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
#[inline]
pub fn iter(&self) -> Iter<Attribute> {
self.0.iter()
}
#[inline]
pub fn iter_mut(&mut self) -> IterMut<Attribute> {
self.0.iter_mut()
}
#[inline]
pub fn iter_svg<'a>(&'a self)
-> Map<SvgAttrFilter, fn(&'a Attribute) -> (AttributeId, &'a Attribute)>
{
fn map_svg(a: &Attribute) -> (AttributeId, &Attribute) { (a.id().unwrap(), a) }
self.filter_svg().map(map_svg)
}
#[inline]
pub fn iter_svg_mut<'a>(&'a mut self)
-> Map<SvgAttrFilterMut, fn(&'a mut Attribute) -> (AttributeId, &'a mut Attribute)>
{
fn map_svg(a: &mut Attribute) -> (AttributeId, &mut Attribute)
{ (a.id().unwrap(), a) }
self.filter_svg_mut().map(map_svg)
}
#[inline]
fn filter_svg(&self) -> SvgAttrFilter {
fn is_svg(a: &&Attribute) -> bool { a.is_svg() }
self.iter().filter(is_svg)
}
#[inline]
fn filter_svg_mut(&mut self) -> SvgAttrFilterMut {
fn is_svg(a: &&mut Attribute) -> bool { a.is_svg() }
self.iter_mut().filter(is_svg)
}
#[inline]
pub fn retain<F>(&mut self, f: F)
where F: FnMut(&Attribute) -> bool
{
self.0.retain(f)
}
}