Switching to bincode implementation for FileLinked
This commit is contained in:
parent
fb78ce77ab
commit
e12b45592c
5 changed files with 60 additions and 22 deletions
|
@ -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"
|
|
@ -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
|
|
@ -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 {
|
||||||
|
|
|
@ -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(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Add table
Reference in a new issue