Created btree macro for easy creation of trees.

This commit is contained in:
Jacob VanDomelen 2019-06-01 04:07:34 -07:00
parent 255e26c95a
commit 87fc26962b
3 changed files with 20 additions and 80 deletions

View file

@ -2,8 +2,9 @@
extern crate clap; extern crate clap;
extern crate regex; extern crate regex;
mod bracket; #[macro_use]
mod tree; mod tree;
mod bracket;
mod constants; mod constants;
mod file_linked; mod file_linked;

View file

@ -20,9 +20,9 @@ fn test_new() {
fn test_fmt() { fn test_fmt() {
assert_eq!( assert_eq!(
format!( format!(
"{}", "{}",
Tree::new("foo", Some(Box::new(Tree::new("bar", None, None))), None) btree!("foo", btree!("bar"),),
), ),
"(foo: (bar: _|_)|_)" "(foo: (bar: _|_)|_)"
); );
} }
@ -30,17 +30,11 @@ fn test_fmt() {
#[test] #[test]
fn test_fmt_node() { fn test_fmt_node() {
assert_eq!( assert_eq!(
Tree::fmt_node(&Some(Box::new(Tree::new( Tree::fmt_node(&Some(Box::new(btree!(17, btree!(16), btree!(12))))),
17,
Some(Box::new(Tree::new(16, None, None))),
Some(Box::new(Tree::new(12, None, None))),
)))),
"17" "17"
); );
assert_eq!( assert_eq!(
Tree::fmt_node(&Some(Box::new( Tree::fmt_node(&Some(Box::new(btree!(btree!("foo"))))),
Tree::new(Tree::new("foo", None, None), None, None),
))),
"(foo: _|_)" "(foo: _|_)"
); );
assert_eq!(Tree::<i32>::fmt_node(&None), "_"); assert_eq!(Tree::<i32>::fmt_node(&None), "_");

View file

@ -9,6 +9,16 @@ pub struct Tree<T> {
pub right: Option<Box<Tree<T>>>, pub right: Option<Box<Tree<T>>>,
} }
#[macro_export]
macro_rules! btree {
($val:expr, $l:expr, $r:expr) => {
$crate::tree::Tree::new($val, Some(Box::new($l)), Some(Box::new($r)))
};
($val:expr, , $r:expr) => { $crate::tree::Tree::new($val, None, Some(Box::new($r))) };
($val:expr, $l:expr,) => { $crate::tree::Tree::new($val, Some(Box::new($l)), None) };
($val:expr) => { Tree::new($val, None, None) };
}
impl<T> Tree<T> { impl<T> Tree<T> {
pub fn new(val: T, left: Option<Box<Tree<T>>>, right: Option<Box<Tree<T>>>) -> Tree<T> { pub fn new(val: T, left: Option<Box<Tree<T>>>, right: Option<Box<Tree<T>>>) -> Tree<T> {
Tree { val, left, right } Tree { val, left, right }
@ -109,76 +119,11 @@ where
type Err = ParseTreeError; type Err = ParseTreeError;
fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut result = Err(ParseTreeError::new(String::from( let result = from_str_helper(s)?;
"Unable to parse tree, string format unreognized.",
)));
let re = Regex::new(r"\(([0-9a-fA-F-]+)\s*:\s*(.*)\)$").unwrap();
let caps = re.captures(s);
if let Some(c) = caps {
let val = T::from_str(c.get(1).unwrap().as_str()).or(Err(
ParseTreeError::new(
format!(
"Unable to parse node value: {}",
c.get(1)
.unwrap()
.as_str()
),
),
))?;
let (left, right) = seperate_nodes(c.get(2).unwrap().as_str())?;
let left = from_str_helper(left)?;
let right = from_str_helper(right)?;
result = Ok(Tree::new(val, left, right));
}
// if let Some(c) = caps {
// result = T::from_str(c.get(1).unwrap().as_str())
// .or(Err(ParseTreeError::new(
// format!("Unable to parse node value: {}", c.get(1).unwrap().as_str()))))
// .and_then(|v| {
// seperate_nodes(c.get(2).unwrap().as_str())
// .and_then(|(left, right)| {
// from_str_helper(left)
// .and_then(|l| {
// from_str_helper(right)
// .and_then(|r| {
// Ok(Tree::new(v, l, r))
// })
// })
// })
// })
// }
// if let Some(c) = caps {
// let val = T::from_str(c.get(1).unwrap().as_str());
// if let Ok(v) = val {
// match seperate_nodes(c.get(2).unwrap().as_str()) {
// Ok((l, r)) => {
// match (from_str_helper(l), from_str_helper(r)) {
// (Ok(left), Ok(right)) => {
// result = Ok(Tree::new(v, left, right));
// },
// (Err(e), _) => {
// result = Err(e);
// },
// (_, Err(e)) => {
// result = Err(e);
// }
// }
// },
// Err(e) => {
// result = Err(e);
// }
// }
// } else {
// result = Err(ParseTreeError::new(
// format!("Unable to parse node value: {}", c.get(1).unwrap().as_str())));
// }
// }
result result
.ok_or(ParseTreeError::new(format!("Unable to parse string {}", s)))
.and_then(|t| Ok(*t))
} }
} }