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 bracket;
|
||||||
mod tree;
|
mod tree;
|
||||||
mod constants;
|
mod constants;
|
||||||
|
mod file_linked;
|
||||||
|
|
||||||
use clap::App;
|
use clap::App;
|
||||||
use std::fs::metadata;
|
use std::fs::metadata;
|
||||||
|
@ -12,6 +13,7 @@ use std::fs::metadata;
|
||||||
/// Runs a simluation of a genetic algorithm against a dataset.
|
/// Runs a simluation of a genetic algorithm against a dataset.
|
||||||
///
|
///
|
||||||
/// Use the -h, --h, or --help flag to see usage syntax.
|
/// Use the -h, --h, or --help flag to see usage syntax.
|
||||||
|
/// 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.
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use regex::Regex;
|
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);
|
let caps = re.captures(s);
|
||||||
|
|
||||||
if let Some(c) = caps {
|
if let Some(c) = caps {
|
||||||
result = T::from_str(c.get(1).unwrap().as_str())
|
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()))))
|
.or(Err(ParseTreeError::new(format!("Unable to parse node value: {}", c.get(1).unwrap().as_str()))))?;
|
||||||
.and_then(|v| {
|
let (left, right) = seperate_nodes(c.get(2).unwrap().as_str())?;
|
||||||
seperate_nodes(c.get(2).unwrap().as_str()).and_then(|(left, right)| {
|
let left = from_str_helper(left)?;
|
||||||
from_str_helper(left).and_then(|l| {
|
let right = from_str_helper(right)?;
|
||||||
from_str_helper(right).and_then(|r| {
|
|
||||||
Ok(Some(Box::new(Tree::new(v, l, r))))
|
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);
|
||||||
}
|
}
|
||||||
|
@ -96,22 +91,34 @@ impl<T> FromStr for Tree<T> where T: FromStr {
|
||||||
let caps = re.captures(s);
|
let caps = re.captures(s);
|
||||||
|
|
||||||
if let Some(c) = caps {
|
if let Some(c) = caps {
|
||||||
result = T::from_str(c.get(1).unwrap().as_str())
|
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()))))
|
.or(Err(ParseTreeError::new(format!("Unable to parse node value: {}", c.get(1).unwrap().as_str()))))?;
|
||||||
.and_then(|v| {
|
let (left, right) = seperate_nodes(c.get(2).unwrap().as_str())?;
|
||||||
seperate_nodes(c.get(2).unwrap().as_str()).and_then(|(left, right)| {
|
let left = from_str_helper(left)?;
|
||||||
from_str_helper(left).and_then(|l| {
|
let right = from_str_helper(right)?;
|
||||||
from_str_helper(right).and_then(|r| {
|
|
||||||
Ok(Tree::new(v, l, r))
|
result = Ok(Tree::new(val, left, right));
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if let Some(c) = caps {
|
// 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 {
|
// 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)) => {
|
||||||
|
|
Loading…
Add table
Reference in a new issue