serde_loader/
lib.rs

1#![doc = r##"Serde wrapper to load/save serializable data from relative paths."##]
2#![doc = r##"
3This crate provides special wrappers to ser/deserialize type from a file path.
4The following wrappers are provided:
5
6"##]
7#![cfg_attr(feature = "json", doc = "- [JsonPath]")]
8#![cfg_attr(feature = "json", doc = "- [JsonPrettyPath]")]
9#![cfg_attr(feature = "json5", doc = "- [Json5Path]")]
10#![cfg_attr(feature = "protobuf", doc = "- [ProtobufPath]")]
11#![doc = ""]
12#![cfg_attr(
13    feature = "json",
14    doc = r##"
15It enables to read or write the file path instead of data during de/serialization.
16For example, we can have a `main.json` file that loads `external.json`.
17
18`main.json`
19
20```json
21{
22    "external": "external.json"
23}
24```
25
26The type type definition is defined as follows.
27
28```no_run
29# fn main() -> anyhow::Result<()> {
30use serde_loader::JsonPath;
31use serde::{Serialize, Deserialize};
32
33#[derive(Serialize, Deserialize)]
34struct Main {
35    pub external: JsonPath<External>
36}
37
38#[derive(Serialize, Deserialize)]
39struct External {
40    data: String
41}
42
43// open file
44let main: JsonPath<Main> = JsonPath::open("main.json")?;
45
46// access data
47let data = &main.external.data;
48# Ok(())
49# }
50```
51
52# Recursive File Loading
53
54The file path is relative to the file where the field is defined.
55It tracks file paths automatically and allows recursive file loading.
56
57Suppose we have the following files.
58
59`main.json`
60
61```json
62{
63    "sub": "sub/sub.json"
64}
65```
66
67`sub/sub.json`
68
69```json
70{
71    "sub": "sub/sub.json"
72}
73```
74
75`sub/sub/sub_of_sub.json`
76
77```json
78{
79    "sub": "sub/sub_of_sub.json"
80}
81```
82
83Let's load the files recursively.
84
85
86```rust
87# fn main() -> anyhow::Result<()> {
88use serde_loader::JsonPath;
89use serde::{Serialize, Deserialize};
90
91#[derive(Serialize, Deserialize)]
92struct Main {
93    pub sub: JsonPath<Sub>
94}
95
96
97#[derive(Serialize, Deserialize)]
98struct Sub {
99    pub sub: JsonPath<SubOfSub>
100}
101
102
103#[derive(Serialize, Deserialize)]
104struct SubOfSub {
105    pub name: String,
106    pub value: String,
107}
108
109let config: JsonPath<Main> = JsonPath::open("tests/config-example/main.json")?;
110config.save()?;
111# Ok(())
112# }
113```
114"##
115)]
116
117mod common;
118mod dir_stack;
119pub mod error;
120
121pub use abs_path_buf::AbsPathBuf;
122pub mod abs_path_buf;
123
124pub use file::FilePath;
125pub mod file;
126
127#[cfg(feature = "protobuf")]
128pub use protobuf::ProtobufPath;
129#[cfg(feature = "protobuf")]
130mod protobuf;
131
132#[cfg(feature = "json")]
133pub use json::{JsonPath, JsonPrettyPath};
134#[cfg(feature = "json")]
135pub mod json;
136
137#[cfg(feature = "json5")]
138pub use self::json5::Json5Path;
139#[cfg(feature = "json5")]
140pub mod json5;
141
142#[cfg(feature = "yaml")]
143pub use self::yaml::YamlPath;
144#[cfg(feature = "yaml")]
145pub mod yaml;