use std::ops::Deref;
use std::ops::DerefMut;
use crate::CriteriumChain;
use crate::CriteriumChainList;
#[derive(Clone, Debug)]
pub enum CriteriumChainBuilderType {
And,
Or,
}
#[derive(Clone, Debug)]
pub struct CriteriumChainBuilder<T> {
pub typ: CriteriumChainBuilderType,
pub list: CriteriumChainList<T>,
}
impl<T> CriteriumChainBuilder<T> {
pub fn new(typ: CriteriumChainBuilderType, fallback: bool) -> Self {
Self {
typ: typ,
list: CriteriumChainList::empty(fallback),
}
}
pub fn and(fallback: bool) -> Self {
Self::new(CriteriumChainBuilderType::And, fallback)
}
pub fn or(fallback: bool) -> Self {
Self::new(CriteriumChainBuilderType::Or, fallback)
}
pub fn to_chain(self) -> CriteriumChain<T> {
match self.typ {
CriteriumChainBuilderType::And => self.list.as_and(),
CriteriumChainBuilderType::Or => self.list.as_or(),
}
}
}
impl<T> Deref for CriteriumChainBuilder<T> {
type Target = CriteriumChainList<T>;
fn deref(&self) -> &Self::Target {
&self.list
}
}
impl<T> DerefMut for CriteriumChainBuilder<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.list
}
}
impl<T> From<CriteriumChainBuilder<T>> for CriteriumChain<T> {
fn from(builder: CriteriumChainBuilder<T>) -> CriteriumChain<T> {
return builder.to_chain();
}
}
impl<T> From<CriteriumChainBuilder<T>> for CriteriumChainList<T> {
fn from(builder: CriteriumChainBuilder<T>) -> CriteriumChainList<T> {
return builder.list;
}
}
impl<T> TryFrom<CriteriumChain<T>> for CriteriumChainBuilder<T> {
type Error = ();
fn try_from(chain: CriteriumChain<T>) -> Result<Self, ()> {
match chain {
CriteriumChain::And(list) => Ok(CriteriumChainBuilder {
typ: CriteriumChainBuilderType::And,
list: list,
}),
CriteriumChain::Or(list) => Ok(CriteriumChainBuilder {
typ: CriteriumChainBuilderType::Or,
list: list,
}),
_ => Err(()),
}
}
}