use std::ops::DerefMut;
use crate::models::{
meta::{AttributeMeta, ElementMeta, EnumerationMetaVariant},
PropertyIdent,
};
pub trait VecHelper {
type Item;
fn find(&mut self, ident: PropertyIdent) -> Option<&mut Self::Item>;
fn find_or_insert<F>(&mut self, ident: PropertyIdent, f: F) -> &mut Self::Item
where
F: FnOnce(PropertyIdent) -> Self::Item;
}
impl<X, T> VecHelper for X
where
X: DerefMut<Target = Vec<T>>,
T: WithIdent,
{
type Item = T;
fn find(&mut self, ident: PropertyIdent) -> Option<&mut Self::Item> {
self.iter_mut().find(|x| x.ident().eq(&ident))
}
fn find_or_insert<F>(&mut self, ident: PropertyIdent, f: F) -> &mut Self::Item
where
F: FnOnce(PropertyIdent) -> Self::Item,
{
let vec = &mut **self;
if let Some(i) = vec.iter().position(|x| x.ident().eq(&ident)) {
&mut vec[i]
} else {
vec.push(f(ident));
vec.last_mut().unwrap()
}
}
}
pub trait WithIdent {
fn ident(&self) -> &PropertyIdent;
}
impl WithIdent for EnumerationMetaVariant {
fn ident(&self) -> &PropertyIdent {
&self.ident
}
}
impl WithIdent for ElementMeta {
fn ident(&self) -> &PropertyIdent {
&self.ident
}
}
impl WithIdent for AttributeMeta {
fn ident(&self) -> &PropertyIdent {
&self.ident
}
}