Finished implementing FileLinked struct.

This commit is contained in:
Jacob VanDomelen 2019-05-31 16:49:39 -07:00
parent 219b00b95d
commit 4252851b81
4 changed files with 104 additions and 27 deletions

View file

@ -1,3 +0,0 @@
trait FileData {
}

View file

@ -0,0 +1,71 @@
use std::fs;
use std::str::FromStr;
use std::fmt::Display;
use std::string::String;
use std::io::Read;
use std::io::Write;
pub struct FileLinked<T> {
val: T,
path: String
}
impl<T: FromStr + Display> FileLinked<T> {
pub fn from_file(path: &str) -> Result<FileLinked<T>, String> {
let meta = fs::metadata(path)
.or(Err(format!("Path {} does not exist.", path)))?;
if meta.is_file() {
let mut file = fs::OpenOptions::new().read(true).open(path)
.or(Err(format!("Unable to open file {}", path)))?;
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.")))?;
Ok(FileLinked {
val,
path: String::from(path)
})
} else {
Err(format!("{} is not a file.", path))
}
}
pub fn new(val: T, path: &str) -> FileLinked<T> {
let result = FileLinked {
val,
path: String::from(path)
};
result.write_data();
result
}
pub fn write_data(&self) -> Result<(), String> {
let mut file = fs::OpenOptions::new()
.write(true)
.create_new(true)
.open(&self.path)
.or(Err(format!("Unable to open path {}", self.path)))?;
write!(file, "{}", self.val)
.or(Err(String::from("Unable to write to file.")))?;
Ok(())
}
pub fn readonly(&self) -> &T {
&self.val
}
pub fn mutate<U, F: FnOnce(&mut T) -> U>(&mut self, op: F) -> U {
let result = op(&mut self.val);
self.write_data();
result
}
}

View file

@ -5,6 +5,7 @@ extern crate regex;
mod bracket;
mod tree;
mod constants;
mod file_linked;
use clap::App;
use std::fs::metadata;
@ -12,6 +13,7 @@ use std::fs::metadata;
/// Runs a simluation of a genetic algorithm against a dataset.
///
/// Use the -h, --h, or --help flag to see usage syntax.
/// TODO
fn main() {
// Command line arguments are parsed with the clap crate. And this program uses
// the yaml method with clap.

View file

@ -1,5 +1,4 @@
use std::fmt;
use std::str::FromStr;
use regex::Regex;
@ -69,17 +68,13 @@ fn from_str_helper<T: FromStr>(s: &str) -> Result<Option<Box<Tree<T>>>, ParseTre
let caps = re.captures(s);
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(Some(Box::new(Tree::new(v, l, r))))
})
})
})
})
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(Some(Box::new(Tree::new(val, left, right))));
} else if emptyre.is_match(s) {
result = Ok(None);
}
@ -96,22 +91,34 @@ impl<T> FromStr for Tree<T> where T: FromStr {
let caps = re.captures(s);
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))
})
})
})
})
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 {
// let val = 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()))))
// .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)) => {