1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
//! Disk: [`serde`](https://docs.rs/serde) + [`directories`](https://docs.rs/directories) + a whole bunch of file formats as [`Traits`](https://doc.rust-lang.org/book/ch10-02-traits.html).
//!
//! This crate is for (de)serializing to/from various file formats (provided by `serde`) to/from disk locations that follow OS-specific specifications/conventions (provided by `directories`). All errors returned will be an [`anyhow::Error`].
//!
//! Example of data being saved on the user's disk for future use:
//! ```
//! use disk::prelude::*; // Necessary imports to get things working.
//! use disk::{Toml,toml_file}; // <- TOML trait & macro.
//! use serde::{Serialize, Deserialize};
//!
//! #[derive(Serialize,Deserialize)] // <- Your data must implement `serde`.
//! struct State {
//! string: String,
//! number: u32,
//! }
//! // To make this struct a file, use the following macro:
//! //
//! // |- 1. The file format used will be TOML.
//! // |
//! // | |- 2. The struct "State" will be used.
//! // | |
//! // | | |- 3. It will be saved in the OS Data directory.
//! // | | |
//! // | | | |- 4. The main project directory is called "MyProject".
//! // | | | |
//! // | | | | |- 6. It won't be in any sub-directories.
//! // | | | | |
//! // | | | | | |- 7. The file name will be "state.toml".
//! // v v v v v v
//! toml_file!(State, Dir::Data, "MyProject", "", "state");
//!
//! // Now our `State` struct implements the `Toml` trait.
//! //
//! // The PATH would look something like:
//! // Windows | C:\Users\Alice\AppData\Roaming\My_Project\state.toml
//! // macOS | /Users/Alice/Library/Application Support/My-Project/state.toml
//! // Linux | /home/alice/.local/share/myproject/state.toml
//!
//! // I'd like to save this to disk, since I'll use it next time.
//! let my_state = State { string: "Hello".to_string(), number: 123 };
//!
//! // Since our `State` struct implements the `Toml` trait, it can do that:
//! match my_state.write() {
//! Ok(_) => println!("We saved to disk"),
//! Err(e) => eprintln!("We failed to save to disk"),
//! }
//!
//! // Let's create a new `State` by reading the file that we just created:
//! let new_state = State::from_file().expect("Failed to read disk");
//!
//! // These should be the same.
//! assert!(my_state == new_state);
//! ```
//! Manually implementing these traits is possible as well, it requires 4 constants to be defined.
//!
//! The file extension (`.bin`, `.toml`, `.json`, `.bson`, etc) is inferred based on what trait you use.
//! ```
//! impl disk::Toml for State {
//! // Which OS directory it will be saved in.
//! const OS_DIRECTORY: disk::Dir = disk::Dir::Data;
//! // Which the main project directory is called.
//! const PROJECT_DIRECTORY: &'static str = "MyProject";
//! // If it should be in any sub-directories.
//! const SUB_DIRECTORIES: &'static str = ""
//! // What the saved filename will be.
//! const FILE_NAME: &'static str = "state";
//! }
//! ```
//!
//! Either a single or multiple sub-directories can be specified with a `/` delimiter.
//!
//! `\` is also allowed but ONLY if building on Windows.
//!
//! An empty string `""` means NO sub directories.
//! ```
//! # use disk::Dir::Data;
//! // Windows ... C:\Users\Alice\AppData\Roaming\My_Project\sub1\sub2\state.toml
//! toml_file!(State, Data, "MyProject", r"sub1\sub2", "state");
//!
//! // macOS ... /Users/Alice/Library/Application Support/My-Project/sub1/sub2/state.json
//! json_file!(State, Data, "MyProject", "sub1/sub2", "state");
//!
//! // Linux ... /home/alice/.local/share/myproject/sub1/sub2/state.yml
//! yaml_file!(State, Data, "MyProject", "sub1/sub2", "state");
//!
//! // NO sub directory:
//! toml_file!(State, Data, "MyProject", "", "state");
//! ```
//!
//! # File Formats
//! | File Format | Feature flag to enable |
//! |-------------|------------------------|
//! | Bincode | `bincode`
//! | JSON | `json`
//! | TOML | `toml`
//! | YAML | `yaml`
//! | Pickle | `pickle`
//! | MessagePack | `messagepack`
//! | BSON | `bson`
//! | Plain Text | `plain`
//
// The "project" directory is taken from the `CARGO_PKG_NAME` environment variable, which should match the `[package.name]` key in your `Cargo.toml`, for example:
// ```toml
// [package]
// name = "my_project"
// ```
// This would create a directory like so:
// ```text
// Windows | C:\Users\Alice\AppData\Roaming\My_Project\
// macOS | /Users/Alice/Library/Application Support/My-Project/
// Linux | /home/alice/.local/share/myproject/
// ```
mod common;
//pub use disk_derive::*;
pub mod prelude {
pub use crate::common::Dir as Dir;
pub use const_format::assertcp as const_assert;
pub use const_format::formatcp as const_format;
}
#[cfg(feature = "bincode")]
mod bincode;
#[cfg(feature = "bincode")]
pub use crate::bincode::Bincode as Bincode;
#[cfg(feature = "json")]
mod json;
#[cfg(feature = "json")]
pub use crate::json::Json as Json;
#[cfg(feature = "toml")]
mod toml;
#[cfg(feature = "toml")]
pub use crate::toml::Toml as Toml;
#[cfg(feature = "yaml")]
mod yaml;
#[cfg(feature = "yaml")]
pub use crate::yaml::Yaml as Yaml;
#[cfg(feature = "pickle")]
mod pickle;
#[cfg(feature = "pickle")]
pub use crate::pickle::Pickle as Pickle;
#[cfg(feature = "messagepack")]
mod messagepack;
#[cfg(feature = "messagepack")]
pub use crate::messagepack::MessagePack as MessagePack;
#[cfg(feature = "bson")]
mod bson;
#[cfg(feature = "bson")]
pub use crate::bson::Bson as Bson;
#[cfg(feature = "plain")]
mod plain;
#[cfg(feature = "plain")]
pub use crate::plain::Plain as Plain;