3 个不稳定版本

0.2.1 2024年1月10日
0.2.0 2023年12月5日
0.1.0 2022年11月3日

#787 in 解析器实现


singlefile-formats 中使用

MIT/Apache

76KB
1K SLoC

SingleFile

Crate Documentation

这个库旨在提供一个简单的读取和写入 Rust 值到磁盘的方法。

用法

singlefile 提供了一个泛型 Container 类型,以及不同用例的类型别名变体。 Container 命名是为了表示它包含并管理文件和值。

// 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()?;

我们期望的结果 my_data.json 应该像这样

{
  "magic_number": 1
}

共享和异步容器

singlefile 还提供了一个 ContainerShared 类型,它可以从多个线程中使用,以及一个 ContainerSharedAsync 类型,它可以从多个线程中使用并异步执行其操作。目前,ContainerSharedAsync 仅保证与 Tokio 一起工作。

可以通过 shared cargo 功能启用共享容器类型。可以通过 shared-async cargo 功能启用异步容器类型。

// 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>(())
  });
});

文件格式

singlefile 是与序列化框架无关的,因此您需要先使用 FileFormat 适配器,然后才能将给定的文件格式写入磁盘。

以下是如何使用 serde 为上述示例编写 Json 适配器

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)
  }
}

或者,您可以使用 singlefile-formats 提供的预设文件格式之一。

功能

默认情况下,仅启用了 tokio-parking-lot 功能。

  • shared:启用 ContainerShared,引入 parking_lot
  • shared-async:启用 ContainerSharedAsync,引入 tokio 和(默认情况下)parking_lot
  • deadlock-detection:如果存在,启用 parking_lotdeadlock_detection 功能。
  • tokio-parking-lot:如果存在,启用 parking_lot 以在 tokio 中使用。默认启用。

依赖项

~2–15MB
~162K SLoC