Continuing FromStr implementation.

This commit is contained in:
Jacob VanDomelen 2019-05-30 23:46:52 -07:00
parent c929e6b3a5
commit 7be7b6282f
4 changed files with 106 additions and 21 deletions

View file

@ -7,3 +7,4 @@ 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"

View file

@ -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;
} }
} }

View file

@ -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;

View file

@ -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> {
pub fn new(val: T, left: Option<Box<Tree<T>>>, right: Option<Box<Tree<T>>>) -> Tree<T> {
Tree { Tree {
val: v, val,
left: l, left,
right: r 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
}
}
} }