From 7be7b6282f117a2b063cb84a50bcfd0a0b4b8ac3 Mon Sep 17 00:00:00 2001 From: Jacob VanDomelen Date: Thu, 30 May 2019 23:46:52 -0700 Subject: [PATCH] Continuing FromStr implementation. --- gemla/Cargo.toml | 3 +- gemla/src/bracket/mod.rs | 18 +++---- gemla/src/main.rs | 6 ++- gemla/src/tree/mod.rs | 100 ++++++++++++++++++++++++++++++++++++--- 4 files changed, 106 insertions(+), 21 deletions(-) diff --git a/gemla/Cargo.toml b/gemla/Cargo.toml index ef45a3e..f27712f 100644 --- a/gemla/Cargo.toml +++ b/gemla/Cargo.toml @@ -6,4 +6,5 @@ edition = "2018" [dependencies] uuid = { version = "0.7", features = ["serde", "v4"] } -clap = { version = "~2.27.0", features = ["yaml"] } \ No newline at end of file +clap = { version = "~2.27.0", features = ["yaml"] } +regex = "1" \ No newline at end of file diff --git a/gemla/src/bracket/mod.rs b/gemla/src/bracket/mod.rs index acfcf65..a688262 100644 --- a/gemla/src/bracket/mod.rs +++ b/gemla/src/bracket/mod.rs @@ -2,7 +2,6 @@ mod state; use super::tree; -use std::str::FromStr; use uuid::Uuid; impl tree::Tree { @@ -13,14 +12,6 @@ impl tree::Tree { } } -impl FromStr for tree::Tree { - type Err = tree::ParseTreeError; - - fn from_str(s: &str) -> Result { - - } -} - // pub struct Bracket { // tree: tree::Tree, // directory: String @@ -33,7 +24,7 @@ fn build_tree(h: u32) -> Option>> { // Recursively building a tree and running the simulation after wards to ensure a bottom-up // execution order. 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 { Some(r) => (*r).run_simulation(), _ => () @@ -55,10 +46,15 @@ pub fn run_bracket() { println!("========================================="); println!("Running bracket..."); 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(); if height == 3 { + println!("{}\n\n", tree); + let s = format!("{}", tree); + println!("{}\n\n", s); + // let tree2: tree::Tree = FromStr::from_str(&s).expect(""); + // println!("{}\n\n", tree2); break; } } diff --git a/gemla/src/main.rs b/gemla/src/main.rs index 094d22a..9493271 100644 --- a/gemla/src/main.rs +++ b/gemla/src/main.rs @@ -1,9 +1,11 @@ +#[macro_use] +extern crate clap; +extern crate regex; + mod bracket; mod tree; mod constants; -#[macro_use] -extern crate clap; use clap::App; use std::fs::metadata; diff --git a/gemla/src/tree/mod.rs b/gemla/src/tree/mod.rs index d03c69e..bb247ef 100644 --- a/gemla/src/tree/mod.rs +++ b/gemla/src/tree/mod.rs @@ -1,16 +1,21 @@ use std::fmt; +use std::str::FromStr; +use regex::Regex; + pub struct Tree { pub val: T, pub left: Option>>, pub right: Option>> } -pub fn combine_trees(v: T, l: Option>>, r: Option>>) -> Tree { - Tree { - val: v, - left: l, - right: r +impl Tree { + pub fn new(val: T, left: Option>>, right: Option>>) -> Tree { + Tree { + val, + left, + right + } } } @@ -34,6 +39,87 @@ pub fn fmt_node(t: &Option>>) -> String { } } -struct ParseTreeError { - msg: String +fn seperate_nodes(s: &str) -> Result<(&str, &str), ParseTreeError> { + let mut result = Err(ParseTreeError::new(format!("Unable to seperate string: {}", s))); + let mut stack: Vec = 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(s: &str) -> Result>>, ParseTreeError> { + let mut result = Err(ParseTreeError::new(String::from("Unable to parse tree, string format unrecognized."))); + + + + result +} + +impl FromStr for Tree { + type Err = ParseTreeError; + + fn from_str(s: &str) -> Result { + 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 + } + } } \ No newline at end of file