Skip to content

Commit

Permalink
feat: Tree view of Predicate result (Case)
Browse files Browse the repository at this point in the history
Finnaly, Fixes assert-rs#7.

Inspired by the work in assert-rs#39.

Created softprops/treeline#3 for trying to find ways to make this more
efficient.
  • Loading branch information
epage committed Jul 21, 2018
1 parent 7d2afb9 commit 34e7f37
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 1 deletion.
4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ appveyor = { repository = "assert-rs/predicates-rs" }
difference = { version = "2.0", optional = true }
regex = { version="1.0", optional = true }
float-cmp = { version="0.4", optional = true }
treeline = { version = "0.1", optional = true }

[features]
default = ["difference", "regex", "float-cmp"]
default = ["difference", "regex", "float-cmp", "tree"]
unstable = []
tree = ["treeline",]
15 changes: 15 additions & 0 deletions examples/case_tree.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
extern crate predicates;

use predicates::prelude::*;
use predicates::tree::CaseTreeExt;

fn main() {
let pred = predicate::ne(5).not().and(predicate::ge(5));

let var = 5;
let case = pred.find_case(true, &var);
if let Some(case) = case {
println!("var is {}", var);
println!("{}", case.tree());
}
}
4 changes: 4 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ extern crate difference;
extern crate float_cmp;
#[cfg(feature = "regex")]
extern crate regex;
#[cfg(feature = "treeline")]
extern crate treeline;

pub mod prelude;

Expand All @@ -121,3 +123,5 @@ pub mod boolean;
pub mod float;
pub mod path;
pub mod str;
#[cfg(feature = "tree")]
pub mod tree;
60 changes: 60 additions & 0 deletions src/tree.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright (c) 2018 The predicates-rs Project Developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/license/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Render `Case` as a tree.

use std::fmt;

use treeline;

use reflection;

/// Render `Self` as a displayable tree.
pub trait CaseTreeExt {
/// Render `Self` as a displayable tree.
fn tree(&self) -> CaseTree;
}

impl<'a> CaseTreeExt for reflection::Case<'a> {
fn tree(&self) -> CaseTree {
CaseTree(convert(self))
}
}

type CaseTreeInner = treeline::Tree<Box<fmt::Display>>;

fn convert<'a>(case: &reflection::Case<'a>) -> CaseTreeInner {
let mut leaves: Vec<CaseTreeInner> = vec![];

leaves.extend(case.predicate().iter().flat_map(|pred| {
pred.parameters().map(|item| {
let root: Box<fmt::Display> = Box::new(item.to_string());
treeline::Tree::new(root, vec![])
})
}));

leaves.extend(case.products().map(|item| {
let root: Box<fmt::Display> = Box::new(item.to_string());
treeline::Tree::new(root, vec![])
}));

leaves.extend(case.children().map(|item| convert(item)));

let root = Box::new(case.predicate().map(|p| p.to_string()).unwrap_or_default());
CaseTreeInner::new(root, leaves)
}

/// A `Case` rendered as a tree for display.
#[allow(missing_debug_implementations)]
pub struct CaseTree(CaseTreeInner);

impl fmt::Display for CaseTree {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(f)
}
}

0 comments on commit 34e7f37

Please sign in to comment.