Created btree macro for easy creation of trees.
This commit is contained in:
parent
255e26c95a
commit
87fc26962b
3 changed files with 20 additions and 80 deletions
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ 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), "_");
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue