aboutsummaryrefslogtreecommitdiff
path: root/lockchain-files/src/fs.rs
diff options
context:
space:
mode:
Diffstat (limited to 'lockchain-files/src/fs.rs')
-rw-r--r--lockchain-files/src/fs.rs81
1 files changed, 36 insertions, 45 deletions
diff --git a/lockchain-files/src/fs.rs b/lockchain-files/src/fs.rs
index be5ccba..1aa57bc 100644
--- a/lockchain-files/src/fs.rs
+++ b/lockchain-files/src/fs.rs
@@ -1,10 +1,10 @@
//! Filesystem abstraction for various data types
-//!
+//!
//! All operations return io::Result<()> to indicate errors
//! and functions that have multiple file endpoints will return
//! a folded error list to indicate which ops were successful
//! and which failed.
-//!
+//!
//! There is also a `From<Vec<?>> for Result<?>` implementation
//! which will return either `Ok(())` or the first error in the list
//! of operations.
@@ -13,20 +13,23 @@ use lcc::traits::AutoEncoder;
use std::collections::HashMap;
use std::error::Error;
-use std::io::{self, Read, Write};
+use std::io::Write;
use std::{
- fs::{self, File, OpenOptions as OO}, path::PathBuf,
+ fs::{self, File, OpenOptions as OO},
+ path::PathBuf,
};
+use utils::FileToString;
+
#[derive(Debug)]
pub struct Filesystem {
- name: String,
- path: String,
- root: PathBuf,
+ pub name: String,
+ pub path: String,
+ pub root: PathBuf,
}
/// A switching enum to determine what type of file to load
-
+#[allow(dead_code)]
pub enum FileType {
/// A data record file
Record,
@@ -34,6 +37,8 @@ pub enum FileType {
Metadata,
/// A simple checksum file
Checksum,
+ #[doc(hidden)]
+ __NonExhaustive,
}
/// Construct a file ending for a specific match result
@@ -42,18 +47,22 @@ macro_rules! file_ending {
match $type {
FileType::Record => "record",
FileType::Metadata => "meta",
+ FileType::Checksum => "sum",
_ => "dat",
}
};
}
impl Filesystem {
- pub fn create(path: &str, name: &str) -> Filesystem {
+ /// Create a new filesystem representation
+ ///
+ /// This function does _not_ touch the disk!
+ pub fn new(path: &str, name: &str) -> Self {
let mut buffer = PathBuf::new();
buffer.push(path);
buffer.push(format!("{}.vault", name));
- Filesystem {
+ Self {
name: name.to_owned(),
path: path.to_owned(),
root: buffer,
@@ -74,27 +83,29 @@ impl Filesystem {
Ok(fs::read_dir(match types {
FileType::Record => self.root.join("records"),
FileType::Metadata => self.root.join("metadata"),
- _ => self.root.join("."),
+ _ => self.root.clone(),
})?.into_iter()
- .filter_map(|r| r.ok())
- .filter(|f| match f.file_type() {
- Ok(vf) => vf.is_file(),
- _ => false,
- })
- .map(|de| de.path())
- .filter_map(|p| p.into_os_string().into_string().ok())
- .filter_map(|s| File::open(s).ok())
- .filter_map(|mut f| f.get_string().ok())
- .filter_map(|s| T::decode(&s).ok())
- .collect())
+ .filter_map(|r| r.ok())
+ .filter(|f| match f.file_type() {
+ Ok(vf) => vf.is_file(),
+ _ => false,
+ }).map(|de| de.path())
+ .filter_map(|p| p.into_os_string().into_string().ok())
+ .filter_map(|s| File::open(s).ok())
+ .filter_map(|mut f| f.get_string().ok())
+ .filter_map(|s| T::decode(&s).ok())
+ .collect())
}
+ /// Retrieve a single record from the cached vault
pub fn pull<T: AutoEncoder>(&self, types: FileType, id: &str) -> Result<T, Box<Error>> {
Ok(T::decode(
- &File::open(self.root.join(&format!("{}.{}", id, file_ending!(types))))?.get_string()?,
+ &File::open(self.root.join(&format!("{}.{}", id, file_ending!(types))))?
+ .get_string()?,
)?)
}
+ /// Respond to a sync request
pub fn sync<T>(&self, data: &HashMap<String, T>, types: FileType) -> Result<(), Box<Error>>
where
T: AutoEncoder,
@@ -110,13 +121,11 @@ impl Filesystem {
}.join(format!("{}.{}", k, file_ending!(types))),
v,
)
- })
- .filter(|(_, v)| v.is_some())
+ }).filter(|(_, v)| v.is_some())
.map(|(k, v)| (k, v.unwrap()))
.map(|(path, data): (PathBuf, String)| {
(OO::new().create(true).write(true).open(path), data)
- })
- .filter(|(path, _)| path.is_ok())
+ }).filter(|(path, _)| path.is_ok())
.map(|(file, data)| (file.unwrap(), data))
.for_each(|(mut file, data)| {
file.write_all(data.as_bytes())
@@ -126,21 +135,3 @@ impl Filesystem {
Ok(())
}
}
-
-/// A utility trait to read the conents from a file in
-/// a single line.
-pub trait FileToString {
- /// Read the file contents into a string without any
- /// error handling.
- fn get_string(&mut self) -> Result<String, io::Error>;
-}
-
-impl FileToString for File {
- fn get_string(&mut self) -> Result<String, io::Error> {
- let mut s = String::new();
- return match self.read_to_string(&mut s) {
- Ok(_) => Ok(s),
- Err(e) => Err(e),
- };
- }
-}