Switching to bincode implementation for FileLinked

This commit is contained in:
vandomej 2021-10-07 02:40:08 -07:00
parent fb78ce77ab
commit e12b45592c
5 changed files with 60 additions and 22 deletions

View file

@ -1,6 +1,6 @@
[package] [package]
name = "file_linked" name = "file_linked"
version = "0.1.0" version = "0.1.2"
authors = ["vandomej <jacob.vandome15@gmail.com>"] authors = ["vandomej <jacob.vandome15@gmail.com>"]
edition = "2018" edition = "2018"
license-file = "../LICENSE" license-file = "../LICENSE"
@ -15,6 +15,6 @@ categories = ["filesystem", "data-structures"]
[dependencies] [dependencies]
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
thiserror = "1.0" thiserror = "1.0"
anyhow = "1.0" anyhow = "1.0"
bincode = "1.3.3"

View file

@ -1 +1,50 @@
# File Linked - controlling objects linked directly to a file # File Linked - controlling objects linked directly to a file
This library provides a wrapper around objects and ties the data to a file. It uses serde and bincode currently for serializing and deserializing the files.
## Examples
```rust
use file_linked::*;
use serde::{Deserialize, Serialize};
use std::fmt;
use std::string::ToString;
use std::path::PathBuf;
#[derive(Deserialize, Serialize)]
struct Test {
pub a: u32,
pub b: String,
pub c: f64
}
let test = Test {
a: 1,
b: String::from("two"),
c: 3.0
};
let file_path = PathBuf::from("./file");
// Object is consumed and can only be interacted with through the FileLinked object
let mut linked_test = FileLinked::new(test, &file_path)?;
// You can obtain a readonly reference of the underlying data
assert_eq!(linked_test.readonly().b, String::from("two"));
// Whenever a mutable operation is performed, the changed data is rewritten to the file
linked_test.mutate(|x| x.a += 1)?;
assert_eq!(linked_test.readonly().a, 2);
drop(linked_test);
// You can also initialize an object from a file
let from_file = FileLinked::<Test>::from_file(&file_path)?;
assert_eq!(from_file.readonly().a, 2);
assert_eq!(from_file.readonly().b, String::from("two"));
assert_eq!(from_file.readonly().c, 3.0);
```
This library is still in development and missing some features and so may not be stable:
- Currently after any mutable operations the FileLinked object will rewrite the entire file
- Custom selection of serializers is not implemented, the serializer used is just bincode as of now

View file

@ -6,14 +6,13 @@ use anyhow::Context;
use serde::de::DeserializeOwned; use serde::de::DeserializeOwned;
use serde::Serialize; use serde::Serialize;
use std::fs::File; use std::fs::File;
use std::io::prelude::*;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use thiserror::Error; use thiserror::Error;
#[derive(Error, Debug)] #[derive(Error, Debug)]
pub enum Error { pub enum Error {
#[error(transparent)] #[error(transparent)]
Serialization(serde_json::Error), Serialization(bincode::Error),
#[error(transparent)] #[error(transparent)]
IO(std::io::Error), IO(std::io::Error),
#[error(transparent)] #[error(transparent)]
@ -116,15 +115,11 @@ where
} }
fn write_data(&self) -> Result<(), Error> { fn write_data(&self) -> Result<(), Error> {
let mut file = File::create(&self.path) let file = File::create(&self.path)
.with_context(|| format!("Unable to open path {}", self.path.display()))?; .with_context(|| format!("Unable to open path {}", self.path.display()))?;
write!( bincode::serialize_into(file, &self.val)
file, .with_context(|| format!("Unable to write to file {}", self.path.display()))?;
"{}",
serde_json::to_string(&self.val).map_err(Error::Serialization)?
)
.with_context(|| format!("Unable to write to file {}", self.path.display()))?;
Ok(()) Ok(())
} }
@ -264,11 +259,7 @@ where
/// .open(&path) /// .open(&path)
/// .expect("Unable to create file"); /// .expect("Unable to create file");
/// ///
/// write!(file, "{}", serde_json::to_string(&test) /// bincode::serialize_into(file, &test).expect("Unable to serialize object");
/// .expect("Unable to serialize object"))
/// .expect("Unable to write file");
///
/// drop(file);
/// ///
/// let mut linked_test = FileLinked::<Test>::from_file(&path) /// let mut linked_test = FileLinked::<Test>::from_file(&path)
/// .expect("Unable to create file linked object"); /// .expect("Unable to create file linked object");
@ -286,7 +277,7 @@ where
let file = let file =
File::open(path).with_context(|| format!("Unable to open file {}", path.display()))?; File::open(path).with_context(|| format!("Unable to open file {}", path.display()))?;
let val = serde_json::from_reader(file) let val = bincode::deserialize_from(file)
.with_context(|| String::from("Unable to parse value from file."))?; .with_context(|| String::from("Unable to parse value from file."))?;
Ok(FileLinked { Ok(FileLinked {

View file

@ -23,8 +23,7 @@ fn main() -> anyhow::Result<()> {
let file_path = matches.value_of(gemla::constants::args::FILE).unwrap(); let file_path = matches.value_of(gemla::constants::args::FILE).unwrap();
let mut gemla = Gemla::<TestState>::new(&PathBuf::from(file_path), true)?; let mut gemla = Gemla::<TestState>::new(&PathBuf::from(file_path), true)?;
gemla.simulate(3)?; gemla.simulate(17)?;
gemla.simulate(1)?;
Ok(()) Ok(())
} }

View file

@ -30,7 +30,6 @@ impl GeneticNode for TestState {
for _ in 0..iterations { for _ in 0..iterations {
self.population = self self.population = self
.population .population
.clone()
.iter() .iter()
.map(|p| p + rng.gen_range(-10..10)) .map(|p| p + rng.gen_range(-10..10))
.collect() .collect()