Continuing FromStr implementation.
This commit is contained in:
parent
c929e6b3a5
commit
7be7b6282f
4 changed files with 106 additions and 21 deletions
|
@ -6,4 +6,5 @@ edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
uuid = { version = "0.7", features = ["serde", "v4"] }
|
uuid = { version = "0.7", features = ["serde", "v4"] }
|
||||||
clap = { version = "~2.27.0", features = ["yaml"] }
|
clap = { version = "~2.27.0", features = ["yaml"] }
|
||||||
|
regex = "1"
|
|
@ -2,7 +2,6 @@ mod state;
|
||||||
|
|
||||||
use super::tree;
|
use super::tree;
|
||||||
|
|
||||||
use std::str::FromStr;
|
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
impl tree::Tree<Uuid> {
|
impl tree::Tree<Uuid> {
|
||||||
|
@ -13,14 +12,6 @@ impl tree::Tree<Uuid> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for tree::Tree<Uuid> {
|
|
||||||
type Err = tree::ParseTreeError;
|
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// pub struct Bracket {
|
// pub struct Bracket {
|
||||||
// tree: tree::Tree,
|
// tree: tree::Tree,
|
||||||
// directory: String
|
// directory: String
|
||||||
|
@ -33,7 +24,7 @@ fn build_tree(h: u32) -> Option<Box<tree::Tree<Uuid>>> {
|
||||||
// Recursively building a tree and running the simulation after wards to ensure a bottom-up
|
// Recursively building a tree and running the simulation after wards to ensure a bottom-up
|
||||||
// execution order.
|
// execution order.
|
||||||
if h != 0 {
|
if h != 0 {
|
||||||
result = Some(Box::new(tree::combine_trees(Uuid::new_v4(), build_tree(h - 1), build_tree(h - 1))));
|
result = Some(Box::new(tree::Tree::new(Uuid::new_v4(), build_tree(h - 1), build_tree(h - 1))));
|
||||||
match &result {
|
match &result {
|
||||||
Some(r) => (*r).run_simulation(),
|
Some(r) => (*r).run_simulation(),
|
||||||
_ => ()
|
_ => ()
|
||||||
|
@ -55,10 +46,15 @@ pub fn run_bracket() {
|
||||||
println!("=========================================");
|
println!("=========================================");
|
||||||
println!("Running bracket...");
|
println!("Running bracket...");
|
||||||
height += 1;
|
height += 1;
|
||||||
tree = tree::combine_trees(Uuid::new_v4(), Some(Box::new(tree)), build_tree(height));
|
tree = tree::Tree::new(Uuid::new_v4(), Some(Box::new(tree)), build_tree(height));
|
||||||
tree.run_simulation();
|
tree.run_simulation();
|
||||||
|
|
||||||
if height == 3 {
|
if height == 3 {
|
||||||
|
println!("{}\n\n", tree);
|
||||||
|
let s = format!("{}", tree);
|
||||||
|
println!("{}\n\n", s);
|
||||||
|
// let tree2: tree::Tree<Uuid> = FromStr::from_str(&s).expect("");
|
||||||
|
// println!("{}\n\n", tree2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
|
#[macro_use]
|
||||||
|
extern crate clap;
|
||||||
|
extern crate regex;
|
||||||
|
|
||||||
mod bracket;
|
mod bracket;
|
||||||
mod tree;
|
mod tree;
|
||||||
mod constants;
|
mod constants;
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate clap;
|
|
||||||
use clap::App;
|
use clap::App;
|
||||||
use std::fs::metadata;
|
use std::fs::metadata;
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,21 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
use std::str::FromStr;
|
||||||
|
use regex::Regex;
|
||||||
|
|
||||||
pub struct Tree<T> {
|
pub struct Tree<T> {
|
||||||
pub val: T,
|
pub val: T,
|
||||||
pub left: Option<Box<Tree<T>>>,
|
pub left: Option<Box<Tree<T>>>,
|
||||||
pub right: Option<Box<Tree<T>>>
|
pub right: Option<Box<Tree<T>>>
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn combine_trees<T>(v: T, l: Option<Box<Tree<T>>>, r: Option<Box<Tree<T>>>) -> Tree<T> {
|
impl<T> Tree<T> {
|
||||||
Tree {
|
pub fn new(val: T, left: Option<Box<Tree<T>>>, right: Option<Box<Tree<T>>>) -> Tree<T> {
|
||||||
val: v,
|
Tree {
|
||||||
left: l,
|
val,
|
||||||
right: r
|
left,
|
||||||
|
right
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +39,87 @@ pub fn fmt_node<T: fmt::Display>(t: &Option<Box<Tree<T>>>) -> String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ParseTreeError {
|
fn seperate_nodes(s: &str) -> Result<(&str, &str), ParseTreeError> {
|
||||||
msg: String
|
let mut result = Err(ParseTreeError::new(format!("Unable to seperate string: {}", s)));
|
||||||
|
let mut stack: Vec<char> = Vec::new();
|
||||||
|
|
||||||
|
for (i, c) in s.char_indices() {
|
||||||
|
if c == '(' {
|
||||||
|
stack.push(c);
|
||||||
|
} else if c == ')' {
|
||||||
|
if stack.is_empty() {
|
||||||
|
result = Err(ParseTreeError::new(format!("Unbalanced parenthesis found in string: {}", s)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
stack.pop();
|
||||||
|
} else if c == '(' && stack.is_empty() {
|
||||||
|
result = Ok((&s[..i], &s[i+1..]));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_str_helper<T>(s: &str) -> Result<Option<Box<Tree<T>>>, ParseTreeError> {
|
||||||
|
let mut result = Err(ParseTreeError::new(String::from("Unable to parse tree, string format unrecognized.")));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: FromStr> FromStr for Tree<T> {
|
||||||
|
type Err = ParseTreeError;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
let mut result = Err(ParseTreeError::new(String::from("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());
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ParseTreeError {
|
||||||
|
pub msg: String
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ParseTreeError {
|
||||||
|
fn new(msg: String) -> ParseTreeError {
|
||||||
|
ParseTreeError {
|
||||||
|
msg
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue