Added rustfmt utility to project.

This commit is contained in:
Jacob VanDomelen 2019-05-31 23:36:42 -07:00
parent feadba1a65
commit 048ea8d564
7 changed files with 302 additions and 249 deletions

View file

@ -7,11 +7,15 @@ use uuid::Uuid;
use std::str::FromStr; use std::str::FromStr;
impl tree::Tree<Uuid> { impl tree::Tree<Uuid> {
pub fn run_simulation(&self) { pub fn run_simulation(&self) {
println!("================================"); println!("================================");
println!("Running simulation for node: {}", self.val); println!("Running simulation for node: {}", self.val);
println!("With children {} and {}", tree::fmt_node(&self.left), tree::fmt_node(&self.right)); println!(
} "With children {} and {}",
tree::fmt_node(&self.left),
tree::fmt_node(&self.right)
);
}
} }
// pub struct Bracket { // pub struct Bracket {
@ -21,46 +25,55 @@ impl tree::Tree<Uuid> {
/// Constructs a tree with a given height while simultaneously running a simulation on each node. /// Constructs a tree with a given height while simultaneously running a simulation on each node.
fn build_tree(h: u32) -> Option<Box<tree::Tree<Uuid>>> { fn build_tree(h: u32) -> Option<Box<tree::Tree<Uuid>>> {
let mut result: Option<Box<tree::Tree<Uuid>>> = None; let mut result: Option<Box<tree::Tree<Uuid>>> = None;
// 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::Tree::new(Uuid::new_v4(), build_tree(h - 1), build_tree(h - 1)))); result = Some(Box::new(tree::Tree::new(
match &result { Uuid::new_v4(),
Some(r) => (*r).run_simulation(), build_tree(h - 1),
_ => () build_tree(h - 1),
} )));
} match &result {
Some(r) => (*r).run_simulation(),
_ => (),
}
}
result result
} }
/// Generates a bracket tree and runs simulation against each node. /// Generates a bracket tree and runs simulation against each node.
/// ///
/// TODO: Explain reasoning for bracket system against genetic algorithm. /// TODO: Explain reasoning for bracket system against genetic algorithm.
pub fn run_bracket() { pub fn run_bracket() {
let mut height = 1; let mut height = 1;
let mut tree = FileLinked::new(*build_tree(height).expect("Error getting result from build_tree"), "temp") let mut tree = FileLinked::new(
.expect("Unable to create file linked object from tree"); *build_tree(height).expect("Error getting result from build_tree"),
"temp",
).expect("Unable to create file linked object from tree");
// Building tree one node at a time, appending to the top. // Building tree one node at a time, appending to the top.
loop { loop {
println!("========================================="); println!("=========================================");
println!("Running bracket..."); println!("Running bracket...");
height += 1; height += 1;
tree.replace(tree::Tree::new(Uuid::new_v4(), Some(Box::new(tree.readonly().clone())), build_tree(height))) tree.replace(tree::Tree::new(
.expect("Error building up tree node"); Uuid::new_v4(),
tree.readonly().run_simulation(); Some(Box::new(tree.readonly().clone())),
build_tree(height),
)).expect("Error building up tree node");
tree.readonly().run_simulation();
if height == 3 { if height == 3 {
println!("{}\n\n", tree); println!("{}\n\n", tree);
let s = format!("{}", tree); let s = format!("{}", tree);
println!("{}\n\n", s); println!("{}\n\n", s);
let tree2: tree::Tree<Uuid> = tree::Tree::from_str(&s).unwrap(); let tree2: tree::Tree<Uuid> = tree::Tree::from_str(&s).unwrap();
println!("{}\n\n", tree2); println!("{}\n\n", tree2);
break; break;
} }
} }
} }

View file

@ -6,91 +6,100 @@ use std::io::Read;
use std::io::Write; use std::io::Write;
pub struct FileLinked<T> { pub struct FileLinked<T> {
val: T, val: T,
path: String path: String,
} }
impl<T> FileLinked<T> where T: FromStr + fmt::Display + Default { impl<T> FileLinked<T>
pub fn from_file(path: &str) -> Result<FileLinked<T>, String> { where
let meta = fs::metadata(path); T: FromStr + fmt::Display + Default,
{
pub fn from_file(path: &str) -> Result<FileLinked<T>, String> {
let meta = fs::metadata(path);
match &meta { match &meta {
Ok(m) if m.is_file() => { Ok(m) if m.is_file() => {
let mut file = fs::OpenOptions::new().read(true).open(path) let mut file = fs::OpenOptions::new().read(true).open(path).or(
.or(Err(format!("Unable to open file {}", path)))?; Err(format!(
let mut s = String::new(); "Unable to open file {}",
file.read_to_string(&mut s) path
.or(Err(String::from("Unable to read from file.")))?; )),
)?;
let mut s = String::new();
file.read_to_string(&mut s).or(Err(String::from(
"Unable to read from file.",
)))?;
let val = T::from_str(&s).or(Err(String::from("Unable to parse value from file.")))?; let val = T::from_str(&s).or(Err(String::from(
"Unable to parse value from file.",
)))?;
Ok(FileLinked { Ok(FileLinked {
val, val,
path: String::from(path) path: String::from(path),
}) })
}, }
Ok(_) => { Ok(_) => Err(format!("{} is not a file.", path)),
Err(format!("{} is not a file.", path)) _ => {
}, let result = FileLinked {
_ => { val: T::default(),
let result = FileLinked { path: String::from(path),
val: T::default(), };
path: String::from(path)
};
result.write_data()?; result.write_data()?;
Ok(result) Ok(result)
} }
} }
} }
pub fn new(val: T, path: &str) -> Result<FileLinked<T>, String> { pub fn new(val: T, path: &str) -> Result<FileLinked<T>, String> {
let result = FileLinked { let result = FileLinked {
val, val,
path: String::from(path) path: String::from(path),
}; };
result.write_data()?; result.write_data()?;
Ok(result) Ok(result)
} }
pub fn write_data(&self) -> Result<(), String> { pub fn write_data(&self) -> Result<(), String> {
let mut file = fs::OpenOptions::new() let mut file = fs::OpenOptions::new()
.write(true) .write(true)
.create(true) .create(true)
.truncate(true) .truncate(true)
.open(&self.path) .open(&self.path)
.or(Err(format!("Unable to open path {}", self.path)))?; .or(Err(format!("Unable to open path {}", self.path)))?;
write!(file, "{}", self.val) write!(file, "{}", self.val).or(Err(String::from(
.or(Err(String::from("Unable to write to file.")))?; "Unable to write to file.",
)))?;
Ok(()) Ok(())
} }
pub fn readonly(&self) -> &T { pub fn readonly(&self) -> &T {
&self.val &self.val
} }
pub fn mutate<U, F: FnOnce(&mut T) -> U>(&mut self, op: F) -> Result<U, String> { pub fn mutate<U, F: FnOnce(&mut T) -> U>(&mut self, op: F) -> Result<U, String> {
let result = op(&mut self.val); let result = op(&mut self.val);
self.write_data()?; self.write_data()?;
Ok(result) Ok(result)
} }
pub fn replace(&mut self, val: T) -> Result<(), String>{ pub fn replace(&mut self, val: T) -> Result<(), String> {
self.val = val; self.val = val;
self.write_data() self.write_data()
} }
} }
impl<T: fmt::Display> fmt::Display for FileLinked<T> { impl<T: fmt::Display> fmt::Display for FileLinked<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.val) write!(f, "{}", self.val)
} }
} }

View file

@ -15,26 +15,28 @@ use std::fs::metadata;
/// Use the -h, --h, or --help flag to see usage syntax. /// Use the -h, --h, or --help flag to see usage syntax.
/// TODO /// TODO
fn main() { fn main() {
// Command line arguments are parsed with the clap crate. And this program uses // Command line arguments are parsed with the clap crate. And this program uses
// the yaml method with clap. // the yaml method with clap.
let yaml = load_yaml!("../cli.yml"); let yaml = load_yaml!("../cli.yml");
let matches = App::from_yaml(yaml).get_matches(); let matches = App::from_yaml(yaml).get_matches();
// Checking that the first argument <DIRECTORY> is a valid directory // Checking that the first argument <DIRECTORY> is a valid directory
let directory = matches.value_of(constants::args::DIRECTORY).unwrap(); let directory = matches.value_of(constants::args::DIRECTORY).unwrap();
let metadata = metadata(directory); let metadata = metadata(directory);
match &metadata { match &metadata {
Ok(m) if m.is_dir() == true => { Ok(m) if m.is_dir() == true => {
println!("{} is a valid directory!", directory); println!("{} is a valid directory!", directory);
println!("Building tree for {}.", directory); println!("Building tree for {}.", directory);
bracket::run_bracket(); bracket::run_bracket();
println!("\n\nReading tree from temp file."); println!("\n\nReading tree from temp file.");
let tree: file_linked::FileLinked<tree::Tree<uuid::Uuid>> = file_linked::FileLinked::from_file("temp") let tree: file_linked::FileLinked<tree::Tree<uuid::Uuid>> =
.expect("Unable to read tree from existing file"); file_linked::FileLinked::from_file("temp").expect(
println!("Value read from file:\n{}", tree); "Unable to read tree from existing file",
}, );
Ok(_) => println!("{} is not a valid directory!", directory), println!("Value read from file:\n{}", tree);
_ => println!("{} does not exist!", directory) }
} Ok(_) => println!("{} is not a valid directory!", directory),
_ => println!("{} does not exist!", directory),
}
} }

View file

@ -4,159 +4,188 @@ use regex::Regex;
#[derive(Default, Clone)] #[derive(Default, Clone)]
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>>>,
} }
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 { Tree { val, left, right }
val, }
left,
right
}
}
} }
impl<T: fmt::Display> fmt::Display for Tree<T> { impl<T: fmt::Display> fmt::Display for Tree<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let node_str = |t: &Option<Box<Tree<T>>>| -> String { let node_str = |t: &Option<Box<Tree<T>>>| -> String {
match t { match t {
Some(n) => format!("{}", *n), Some(n) => format!("{}", *n),
_ => String::from("_") _ => String::from("_"),
} }
}; };
write!(f, "({} :{}|{})", self.val, node_str(&self.left), node_str(&self.right)) write!(
} f,
"({} :{}|{})",
self.val,
node_str(&self.left),
node_str(&self.right)
)
}
} }
pub fn fmt_node<T: fmt::Display>(t: &Option<Box<Tree<T>>>) -> String { pub fn fmt_node<T: fmt::Display>(t: &Option<Box<Tree<T>>>) -> String {
match t { match t {
Some(n) => format!("{}", (*n).val), Some(n) => format!("{}", (*n).val),
_ => String::from("_") _ => String::from("_"),
} }
} }
fn seperate_nodes(s: &str) -> Result<(&str, &str), ParseTreeError> { fn seperate_nodes(s: &str) -> Result<(&str, &str), ParseTreeError> {
let mut result = Err(ParseTreeError::new(format!("Unable to seperate string: {}", s))); let mut result = Err(ParseTreeError::new(
let mut stack: Vec<char> = Vec::new(); format!("Unable to seperate string: {}", s),
));
let mut stack: Vec<char> = Vec::new();
for (i, c) in s.char_indices() { for (i, c) in s.char_indices() {
if c == '(' { if c == '(' {
stack.push(c); stack.push(c);
} else if c == ')' { } else if c == ')' {
if stack.is_empty() { if stack.is_empty() {
result = Err(ParseTreeError::new(format!("Unbalanced parenthesis found in string: {}", s))); result = Err(ParseTreeError::new(
break; format!("Unbalanced parenthesis found in string: {}", s),
} ));
break;
}
stack.pop(); stack.pop();
} else if c == '|' && stack.is_empty() { } else if c == '|' && stack.is_empty() {
result = Ok((&s[..i], &s[i+1..])); result = Ok((&s[..i], &s[i + 1..]));
break; break;
} }
} }
result result
} }
fn from_str_helper<T: FromStr>(s: &str) -> Result<Option<Box<Tree<T>>>, ParseTreeError> { fn from_str_helper<T: FromStr>(s: &str) -> Result<Option<Box<Tree<T>>>, ParseTreeError> {
let mut result = Err(ParseTreeError::new(String::from("Unable to parse tree, string format unrecognized."))); let mut result = Err(ParseTreeError::new(String::from(
let emptyre = Regex::new(r"\s*_\s*").unwrap(); "Unable to parse tree, string format unrecognized.",
let re = Regex::new(r"\(([0-9a-fA-F-]+)\s*:\s*(.*)\)$").unwrap(); )));
let caps = re.captures(s); let emptyre = Regex::new(r"\s*_\s*").unwrap();
let re = Regex::new(r"\(([0-9a-fA-F-]+)\s*:\s*(.*)\)$").unwrap();
let caps = re.captures(s);
if let Some(c) = caps { if let Some(c) = caps {
let val = T::from_str(c.get(1).unwrap().as_str()) let val = T::from_str(c.get(1).unwrap().as_str()).or(Err(
.or(Err(ParseTreeError::new(format!("Unable to parse node value: {}", c.get(1).unwrap().as_str()))))?; ParseTreeError::new(
let (left, right) = seperate_nodes(c.get(2).unwrap().as_str())?; format!(
let left = from_str_helper(left)?; "Unable to parse node value: {}",
let right = from_str_helper(right)?; 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(Some(Box::new(Tree::new(val, left, right)))); result = Ok(Some(Box::new(Tree::new(val, left, right))));
} else if emptyre.is_match(s) { } else if emptyre.is_match(s) {
result = Ok(None); result = Ok(None);
} }
result result
} }
impl<T> FromStr for Tree<T> where T: FromStr { impl<T> FromStr for Tree<T>
type Err = ParseTreeError; where
T: FromStr,
{
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("Unable to parse tree, string format unreognized."))); let mut result = Err(ParseTreeError::new(String::from(
let re = Regex::new(r"\(([0-9a-fA-F-]+)\s*:\s*(.*)\)$").unwrap(); "Unable to parse tree, string format unreognized.",
let caps = re.captures(s); )));
let re = Regex::new(r"\(([0-9a-fA-F-]+)\s*:\s*(.*)\)$").unwrap();
let caps = re.captures(s);
if let Some(c) = caps { if let Some(c) = caps {
let val = T::from_str(c.get(1).unwrap().as_str()) let val = T::from_str(c.get(1).unwrap().as_str()).or(Err(
.or(Err(ParseTreeError::new(format!("Unable to parse node value: {}", c.get(1).unwrap().as_str()))))?; ParseTreeError::new(
let (left, right) = seperate_nodes(c.get(2).unwrap().as_str())?; format!(
let left = from_str_helper(left)?; "Unable to parse node value: {}",
let right = from_str_helper(right)?; 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)); result = Ok(Tree::new(val, left, right));
} }
// if let Some(c) = caps { // if let Some(c) = caps {
// result = T::from_str(c.get(1).unwrap().as_str()) // 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())))) // .or(Err(ParseTreeError::new(
// .and_then(|v| { // format!("Unable to parse node value: {}", c.get(1).unwrap().as_str()))))
// seperate_nodes(c.get(2).unwrap().as_str()) // .and_then(|v| {
// .and_then(|(left, right)| { // seperate_nodes(c.get(2).unwrap().as_str())
// from_str_helper(left) // .and_then(|(left, right)| {
// .and_then(|l| { // from_str_helper(left)
// from_str_helper(right) // .and_then(|l| {
// .and_then(|r| { // from_str_helper(right)
// Ok(Tree::new(v, l, r)) // .and_then(|r| {
// }) // Ok(Tree::new(v, l, r))
// }) // })
// }) // })
// }) // })
// } // })
// }
// if let Some(c) = caps { // if let Some(c) = caps {
// let val = T::from_str(c.get(1).unwrap().as_str()); // let val = T::from_str(c.get(1).unwrap().as_str());
// if let Ok(v) = val { // if let Ok(v) = val {
// match seperate_nodes(c.get(2).unwrap().as_str()) { // match seperate_nodes(c.get(2).unwrap().as_str()) {
// Ok((l, r)) => { // Ok((l, r)) => {
// match (from_str_helper(l), from_str_helper(r)) { // match (from_str_helper(l), from_str_helper(r)) {
// (Ok(left), Ok(right)) => { // (Ok(left), Ok(right)) => {
// result = Ok(Tree::new(v, left, right)); // result = Ok(Tree::new(v, left, right));
// }, // },
// (Err(e), _) => { // (Err(e), _) => {
// result = Err(e); // result = Err(e);
// }, // },
// (_, Err(e)) => { // (_, Err(e)) => {
// result = Err(e); // result = Err(e);
// } // }
// } // }
// }, // },
// Err(e) => { // Err(e) => {
// result = Err(e); // result = Err(e);
// } // }
// } // }
// } else { // } else {
// result = Err(ParseTreeError::new(format!("Unable to parse node value: {}", c.get(1).unwrap().as_str()))); // result = Err(ParseTreeError::new(
// } // format!("Unable to parse node value: {}", c.get(1).unwrap().as_str())));
// } // }
// }
result result
} }
} }
#[derive(Debug)] #[derive(Debug)]
pub struct ParseTreeError { pub struct ParseTreeError {
pub msg: String pub msg: String,
} }
impl ParseTreeError { impl ParseTreeError {
fn new(msg: String) -> ParseTreeError { fn new(msg: String) -> ParseTreeError {
ParseTreeError { ParseTreeError { msg }
msg }
}
}
} }