use std::borrow;
use std::fmt;
use std::slice;
pub trait PredicateReflection: fmt::Display {
fn parameters<'a>(&'a self) -> Box<dyn Iterator<Item = Parameter<'a>> + 'a> {
let params = vec![];
Box::new(params.into_iter())
}
fn children<'a>(&'a self) -> Box<dyn Iterator<Item = Child<'a>> + 'a> {
let params = vec![];
Box::new(params.into_iter())
}
}
pub struct Parameter<'a>(&'a str, &'a dyn fmt::Display);
impl<'a> Parameter<'a> {
pub fn new(key: &'a str, value: &'a dyn fmt::Display) -> Self {
Self(key, value)
}
pub fn name(&self) -> &str {
self.0
}
pub fn value(&self) -> &dyn fmt::Display {
self.1
}
}
impl<'a> fmt::Display for Parameter<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}: {}", self.0, self.1)
}
}
impl<'a> fmt::Debug for Parameter<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "({:?}, {})", self.0, self.1)
}
}
pub struct Child<'a>(&'a str, &'a dyn PredicateReflection);
impl<'a> Child<'a> {
pub fn new(key: &'a str, value: &'a dyn PredicateReflection) -> Self {
Self(key, value)
}
pub fn name(&self) -> &str {
self.0
}
pub fn value(&self) -> &dyn PredicateReflection {
self.1
}
}
impl<'a> fmt::Display for Child<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}: {}", self.0, self.1)
}
}
impl<'a> fmt::Debug for Child<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "({:?}, {})", self.0, self.1)
}
}
pub struct Case<'a> {
predicate: Option<&'a dyn PredicateReflection>,
result: bool,
products: Vec<Product>,
children: Vec<Case<'a>>,
}
impl<'a> Case<'a> {
pub fn new(predicate: Option<&'a dyn PredicateReflection>, result: bool) -> Self {
Self {
predicate,
result,
products: Default::default(),
children: Default::default(),
}
}
pub fn add_product(mut self, product: Product) -> Self {
self.products.push(product);
self
}
pub fn add_child(mut self, child: Case<'a>) -> Self {
self.children.push(child);
self
}
pub fn predicate(&self) -> Option<&dyn PredicateReflection> {
self.predicate
}
pub fn result(&self) -> bool {
self.result
}
pub fn products(&self) -> CaseProducts<'_> {
CaseProducts(self.products.iter())
}
pub fn children(&self) -> CaseChildren<'_> {
CaseChildren(self.children.iter())
}
}
impl<'a> fmt::Debug for Case<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let predicate = if let Some(ref predicate) = self.predicate {
format!("Some({})", predicate)
} else {
"None".to_owned()
};
f.debug_struct("Case")
.field("predicate", &predicate)
.field("result", &self.result)
.field("products", &self.products)
.field("children", &self.children)
.finish()
}
}
#[derive(Debug, Clone)]
pub struct CaseProducts<'a>(slice::Iter<'a, Product>);
impl<'a> Iterator for CaseProducts<'a> {
type Item = &'a Product;
fn next(&mut self) -> Option<&'a Product> {
self.0.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
fn count(self) -> usize {
self.0.count()
}
}
#[derive(Debug, Clone)]
pub struct CaseChildren<'a>(slice::Iter<'a, Case<'a>>);
impl<'a> Iterator for CaseChildren<'a> {
type Item = &'a Case<'a>;
fn next(&mut self) -> Option<&'a Case<'a>> {
self.0.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
fn count(self) -> usize {
self.0.count()
}
}
pub struct Product(borrow::Cow<'static, str>, Box<dyn fmt::Display>);
impl Product {
pub fn new<S, D>(key: S, value: D) -> Self
where
S: Into<borrow::Cow<'static, str>>,
D: fmt::Display + 'static,
{
Self(key.into(), Box::new(value))
}
pub fn name(&self) -> &str {
self.0.as_ref()
}
pub fn value(&self) -> &dyn fmt::Display {
&self.1
}
}
impl fmt::Display for Product {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}: {}", self.0, self.1)
}
}
impl fmt::Debug for Product {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "({:?}, {})", self.0, self.1)
}
}