#[cfg(feature = "serde")]
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::iter::FromIterator;
use std::slice::Iter;
use crate::CriteriumChain;
#[derive(Clone, Debug, Default)]
pub struct CriteriumChainList<T> {
pub criteria: Vec<CriteriumChain<T>>,
pub fallback: bool,
}
impl<T> CriteriumChainList<T> {
pub fn new(list: Vec<CriteriumChain<T>>, fallback: bool) -> Self {
Self {
criteria: list,
fallback: fallback,
}
}
pub fn empty(fallback: bool) -> Self {
Self {
criteria: Vec::new(),
fallback: fallback,
}
}
pub fn as_and(self) -> CriteriumChain<T> {
CriteriumChain::And(self)
}
pub fn as_or(self) -> CriteriumChain<T> {
CriteriumChain::Or(self)
}
#[inline]
pub fn len(&self) -> usize {
self.criteria.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.criteria.is_empty()
}
pub fn map<B, F>(self, f: F) -> CriteriumChainList<B>
where
F: FnMut(CriteriumChain<T>) -> CriteriumChain<B>,
{
CriteriumChainList::new(self.criteria.into_iter().map(f).collect(), self.fallback)
}
pub fn for_each<F>(&self, f: F)
where
F: FnMut(&CriteriumChain<T>),
{
self.criteria.iter().for_each(f);
}
pub fn add_criterium(&mut self, entry: T) {
self.criteria.push(CriteriumChain::Match(entry));
}
pub fn add_criterium_inverted(&mut self, entry: T) {
self.criteria.push(CriteriumChain::Not(entry));
}
pub fn add_criterium_invertable(&mut self, entry: T, invert: bool) {
if invert {
self.add_criterium_inverted(entry);
} else {
self.add_criterium(entry);
}
}
pub fn add_some_criterium(&mut self, entry: Option<T>) {
if let Some(entry) = entry {
self.criteria.push(CriteriumChain::Match(entry));
}
}
pub fn add_some_criterium_inverted(&mut self, entry: Option<T>) {
if let Some(entry) = entry {
self.criteria.push(CriteriumChain::Not(entry));
}
}
pub fn add_some_criterium_invertable(&mut self, entry: Option<T>, invert: bool) {
if let Some(entry) = entry {
if invert {
self.add_criterium_inverted(entry);
} else {
self.add_criterium(entry);
}
}
}
pub fn add_chain(&mut self, chain: CriteriumChain<T>) {
self.criteria.push(chain);
}
pub fn add_some_chain(&mut self, chain: Option<CriteriumChain<T>>) {
if let Some(chain) = chain {
self.add_chain(chain);
}
}
}
impl<T> From<Vec<CriteriumChain<T>>> for CriteriumChainList<T> {
fn from(chain_list: Vec<CriteriumChain<T>>) -> Self {
Self {
criteria: chain_list,
fallback: false,
}
}
}
impl<T> FromIterator<CriteriumChain<T>> for CriteriumChainList<T> {
fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = CriteriumChain<T>>,
{
Self {
criteria: iter.into_iter().collect(),
fallback: false,
}
}
}
impl<'a, T> IntoIterator for &'a CriteriumChainList<T> {
type Item = &'a CriteriumChain<T>;
type IntoIter = Iter<'a, CriteriumChain<T>>;
fn into_iter(self) -> Self::IntoIter {
self.criteria.iter()
}
}
impl<'a, T> IntoIterator for &'a mut CriteriumChainList<T> {
type Item = &'a CriteriumChain<T>;
type IntoIter = Iter<'a, CriteriumChain<T>>;
fn into_iter(self) -> Self::IntoIter {
self.criteria.iter()
}
}
#[cfg(feature = "serde")]
impl<T> Serialize for CriteriumChainList<T>
where
T: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
if !self.is_empty() {
return self.criteria.serialize(serializer);
} else {
return vec![CriteriumChain::<T>::constant(self.fallback)].serialize(serializer);
}
}
}
#[cfg(feature = "serde")]
impl<'de, T> Deserialize<'de> for CriteriumChainList<T>
where
T: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
return Ok(Self {
criteria: Vec::deserialize(deserializer)?,
fallback: false,
});
}
}