Finished implementing FileLinked struct.
This commit is contained in:
parent
219b00b95d
commit
4252851b81
4 changed files with 104 additions and 27 deletions
|
@ -1,3 +0,0 @@
|
|||
trait FileData {
|
||||
|
||||
}
|
71
gemla/src/file_linked/mod.rs
Normal file
71
gemla/src/file_linked/mod.rs
Normal 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
|
||||
}
|
||||
}
|
|
@ -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.
|
||||
|
|
|
@ -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)) => {
|
||||
|
|
Loading…
Add table
Reference in a new issue