#save-file #local-file #struct #save-load #game #load-file #wrapper

localsavefile

从本地文件保存和加载结构体。是对 savefile crate 的便捷包装。

6 个版本

0.2.3 2024 年 8 月 21 日
0.2.2 2024 年 8 月 4 日
0.1.3 2024 年 8 月 1 日
0.1.2 2024 年 7 月 28 日

#5#load-file

Download history 305/week @ 2024-07-27 258/week @ 2024-08-03 12/week @ 2024-08-10

575 每月下载量
用于 bandmix

MIT/Apache

22KB
355

LocalSaveFile

Crates.io Docs.rs CI

关于 - 用法 - 相关 - 许可

关于

从本地文件保存和加载结构体。是对 savefile crate 的便捷包装。

LocalSaveFile 负责管理结构体应该保存在磁盘上的位置和方式。 savefile 允许对 Rust 数据结构的序列化和压缩,而 directories-rs 决定该文件应该放在哪里。

这个 crate 不适合用作数据库或比简单的 结构体 更复杂的任何东西。从 savefile 继承而来,这个 crate 可以用于,例如,游戏中的保存文件。

为什么

我一直在用 Rust 制作一些玩具程序,并不断发现需要某种形式的持久存储。我不想使用任何复杂的实现,因此,给结构体附加属性的想法似乎是个好主意。

用法

[!NOTE] 目前,只有 结构体 被测试,并且是这个 crate 的作用域。

要求

Cargo

cargo add localsavefile savefile

[!IMPORTANT] 由于这主要是一个便捷包装,因此还需要通过 cargo 添加 savefile 才能使用导出的宏。

最小示例

[!NOTE] Default 和 Savefile 宏自动设置为 derive。无论如何,使用 localsavefile_impl 而不是 localsavefile 来手动 derive。

use localsavefile::{localsavefile, LocalSaveFile, LocalSaveFileCommon};

#[localsavefile]
struct MySave {
    val: u32,
}

let foo = MySave { val: 21 };
foo.save();
let bar = MySave::load_default();
let mut baz = MySave { val: 42 };
baz.load();
assert_eq!(foo.val, bar.val); // Should never trigger
assert_eq!(bar.val, foo.val); // Should never trigger
MySave::remove_file(); // Removes the default file

[!WARNING] 如果出于任何原因在库中实现 localsavefile,建议重新导出宏 setlsf 并在用户调用此宏之前进行操作。它将设置环境变量 LOCAL_SAVE_FILE_CARGO_PKG_NAMELOCAL_SAVE_FILE_CARGO_PKG_AUTHORS 以代替分别使用 CARGO_PKG_NAMECARGO_PKG_AUTHORS。否则,默认路径将相对于您的 crate,而不是用户。

// In lib.rs, probably
pub use localsavefile::setlsf;

持久化文件

如果您希望保持底层文件始终打开,即不需要在每次调用 saveload 时重新打开它,可以通过参数 persist = true 将文件句柄添加到您的结构体中。这将修改您的结构体并添加一个额外字段。其用法与非持久化版本相同,但有一些注意事项,如下所示。

[!TIP] 我没有测试过保留持久化元数据是否有实际的好处。如果您不确定,请使用非持久化版本。

[!NOTE] 持久化本地保存文件将在加载或保存时存储其路径。这意味着任何后续的 setlsf 调用都不会影响它。

use localsavefile::{localsavefile, LocalSaveFilePersistent, LocalSaveFileCommon};

#[localsavefile(persist = true)]
struct MySavePersist {
    val: u32,
}

let mut foo = MySavePersist {
    val: 21,
    // If you must create an inline struct, make use of your IDE to auto fill the following
    __place_localsavefile_above_any_derives: Default::default(),
};
// foo.open_default(); // You should call open or open_default first
// but foo.save() will also open_default if needed
foo.save(); // Save now requires foo to be mutable
let mut bar = MySavePersist::load_default();
assert_eq!(foo.val, bar.val); // Should never trigger
foo.close();
bar.close(); // Requires bar to be mutable
// Close any instances before removing the file
MySavePersist::remove_file(); // Removes the default file

[!CAUTION] 因为 localsavefile(persist = true) 修改了您的结构体,所以在使用 localsavefile_impl 时,必须将其放置在所有必须了解每个字段的 derives 之前,例如。

// First localsavefile
#[localsavefile_impl(persist = true)]
// Then whatever else ...
#[derive(Savefile, Default)]
struct MySave {
    val: u32,
    // HIDDEN: __place_localsavefile_above_any_derives : Option<File>
}

在这种情况下,这确保了添加的字段会被 DefaultSavefile 处理。

透传函数

内部功能被公开,以便可以直接控制加载和保存操作中使用的文件。这些路径不会被保存,并立即用于相应的操作。

use localsavefile::{localsavefile, LocalSaveFile, LocalSaveFileCommon};

#[localsavefile]
struct MySave {
    val: u32,
}

let foo = MySave::load_file_or_default("./data.bin");
foo.load_file("./other_data.bin");
foo.save_file("./this_data.bin");

// Replaces the default file
MySave::replace_file("./this_data.bin");

[!IMPORTANT] 不会检查文件目录是否有效。尤其是当保存到文件时。

[!NOTE] load_file_or_defaultload_filesave_file 忽略 setlsf 的使用,因为路径会立即使用。

选项

默认情况下,底层文件名基于从定义结构体的位置调用的 module_path! 的清理组合,以及结构体名称。

存储文件的目录基于 directories::ProjectDirs.data_dir,其中使用 Cargo.toml 中的名称和第一个作者作为参数。作者不需要定义,但应该定义。

正如您所想象的,改变这些默认值使用的任何内容都会悄悄地改变您的结构体加载的内容。以下选项允许覆盖所提及的任何值以保持静态路径。

#[localsavefile(name = "a_unique_name", path = "./a/valid/path")]
struct TestStruct {
    val: u32,
    str: String,
}

以下是在我的 Windows 机器上使用 localsavefile-test 时,最小示例 将输出的内容。

C:\\Users\\%USER%\\AppData\\Roaming\\localsavefile-test-author🧪\\localsavefile-test\\data\\localsavefile_test.mysave.bin

版本选项接受一个 u32 并传递给底层的 savefile crate。有关更多信息,请参阅该 crate 的 版本部分,因为这与该结构体仍然相关。

#[localsavefile(version = 1)]
struct TestStruct {
    val: u32,
    #[savefile_default_val = "not-blank"]
    #[savefile_versions = "0..0"]
    str: String,
}

许可证

根据以下任一许可证授权:

任选。

依赖项

~8-17MB
~216K SLoC