Expand description
This library is designed to be a dead-simple way of reading and writing your rust values to and from disk.
§Usage
singlefile
provides a generic Container
type, along with type alias variants for different use cases.
Container
is named so to indicate that it contains and manages a file and a value.
// A readable, writable container
use singlefile::container::ContainerWritable;
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, Default)]
struct MyData {
magic_number: i32
}
// Attempts to open 'my_data.json', creating it from default if it does not exist,
// expecting data that the `Json` format can decode into `MyData`
let mut my_container = ContainerWritable::<MyData, Json>::create_or_default("my_data.json", Json)?;
// For regular `Container`s, `Deref` and `DerefMut` can be used to access the contained type
println!("magic_number: {}", my_container.magic_number); // 0 (as long as the file didn't exist before)
my_container.magic_number += 1;
// Write the new state of `MyData` to disk
my_container.commit()?;
We’d then expect the resulting my_data.json
to look like:
{
"magic_number": 1
}
§Shared and async containers
singlefile
also provides a ContainerShared
type that can be used from multiple threads, as well as
a ContainerSharedAsync
that can be used from multiple threads and spawns its operations asynchronously.
Currently, ContainerSharedAsync
can only be guaranteed to work alongside Tokio.
The shared container types can be enabled with the shared
cargo feature.
The async container types can be enabled with the shared-async
cargo feature.
// A readable, writable container with multiple-ownership
use singlefile::container_shared::ContainerSharedWritable;
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, Default)]
struct MyData {
magic_number: i32
}
// `ContainerShared` types may be cloned cheaply, they behave like `Arc`s
let my_container = ContainerSharedWritable::<MyData, Json>::create_or_default("my_data.json", Json)?;
// Get access to the contained `MyData`, increment it, and commit changes to disk
std::thread::spawn(move || {
my_container.operate_mut_commit(|my_data| {
my_data.magic_number += 1;
Ok::<(), Infallible>(())
});
});
§File formats
singlefile
is serialization framework-agnostic, so you will need a FileFormat
adapter
before you are able to read and write a given file format to disk.
Here is how you’d write a Json
adapter for the above examples, using serde
.
use serde::ser::Serialize;
use serde::de::DeserializeOwned;
use singlefile::FileFormat;
use std::io::{Read, Write};
struct Json;
impl<T> FileFormat<T> for Json
where T: Serialize + DeserializeOwned {
type FormatError = serde_json::Error;
fn to_writer<W: Write>(&self, writer: W, value: &T) -> Result<(), Self::FormatError> {
serde_json::to_writer_pretty(writer, value).map_err(From::from)
}
fn from_reader<R: Read>(&self, reader: R) -> Result<T, Self::FormatError> {
serde_json::from_reader(reader).map_err(From::from)
}
}
Alternatively, you can use one of the preset file formats provided by
singlefile-formats
.
§Features
By default, only the tokio-parking-lot
feature is enabled.
shared
: EnablesContainerShared
, pulling inparking_lot
.shared-async
: EnablesContainerSharedAsync
, pulling intokio
and (by default)parking_lot
.fs-err2
: Enables this crate to usefs-err
v2 for everything filesystem-related.fs-err3
: Enables this crate to usefs-err
v3 for everything filesystem-related. Overridesfs-err2
if present.fs-err
: An alias for thefs-err3
feature (and will correspond to the latest version offs-err
going forwards).deadlock-detection
: Enablesparking_lot
’sdeadlock_detection
feature, if it is present.tokio-parking-lot
: Enablesparking_lot
for use intokio
, if it is present. Enabled by default.
Re-exports§
Modules§
- container
- Container constructs providing single-ownership managed access to a file.
- container_
shared shared
- Container constructs allowing multiple-ownership managed access to a file.
- container_
shared_ async shared-async
- Container constructs allowing multiple-ownership, asynchronous, managed access to a file.
- error
- Errors that can occur within
singlefile
. - fs
- Utility module re-exporting filesystem functions.
- manager
- This module contains the
FileManager
struct which gives more direct access to a file. - utils
- Utility functions.
Traits§
- File
Format - A trait that describes how a file’s contents should be interpreted.
- File
Format Utf8 - A trait that indicates a file’s contents will always be valid UTF-8.