Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
debug/
target/

# Testing-specific
config/

# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock
Expand Down
45 changes: 3 additions & 42 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,42 +1,3 @@
[package]
name = "fast_config"
version = "1.2.1"
edition = "2021"
authors = ["FlooferLand"]
description = "A small and simple multi-format crate to handle config files"
keywords = ["settings", "config", "configuration", "simple", "json5"]
categories = ["config"]
exclude = ["src/tests.rs", "test.cmd"]

# GitHub stuff
readme = "README.md"
license = "MIT"
documentation = "https://docs.rs/fast_config"
repository = "https://github.com/FlooferLand/fast_config"

[package.metadata.docs.rs]
all-features = true

[badges]
maintenance = { status = "actively-developed" }

[dev-dependencies]
env_logger = "0.11"

[dependencies]
serde = { version = "1.0", features = ["derive"], optional = false }
log = "0.4"
thiserror = "1.0"

# Optional
json5 = { version = "0.4", optional = true }
toml = { version = "0.8", optional = true }
serde_yml = { version = "0.0", optional = true }
serde_json = { version = "1.0", optional = true }

[features]
default = []
json = ["dep:serde_json"]
json5 = ["dep:json5", "dep:serde_json"]
toml = ["dep:toml"]
yaml = ["dep:serde_yml"]
[workspace]
resolver = "3"
members = ["fast_config", "fast_config_derive"]
173 changes: 129 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@

A small, safe, lightweight, and easy-to-use Rust crate to read and write to config files.

Currently only supports:
[JSON](https://crates.io/crates/serde_json) & [JSON5](https://crates.io/crates/json5), [TOML](https://crates.io/crates/toml), and [YAML](https://crates.io/crates/serde_yml).
Currently supports:
[JSON](https://crates.io/crates/serde_json), [JSON5](https://crates.io/crates/json5), [TOML](https://crates.io/crates/toml), and [YAML](https://crates.io/crates/serde_yml).

But more [Serde](https://serde.rs/)-supported formats *(such as RON)* are planned to be added later.

Expand Down Expand Up @@ -61,73 +61,158 @@ anything that isn't working as expected!
---

## Examples:

### Basic Usage

```rust
use fast_config::Config;
use serde::{Serialize, Deserialize};
use fast_config::FastConfig;
use fast_config::Format;
use serde::Serialize;
use serde::Deserialize;

// Creating a config struct to store our data
#[derive(Serialize, Deserialize)]
// Create a config struct and derive FastConfig
#[derive(Serialize, Deserialize, FastConfig)]
pub struct MyData {
pub student_debt: i32,
}

fn main() {
// Initializing a logging system (needed to show some warnings/errors)
env_logger::init();
// Create the data with default values
let mut data = MyData {
student_debt: 20
};

// Creating our data (default values)
let data = MyData {
student_debt: 20,
};
// Save to create the file
data.save("test/myconfig.json5", Format::JSON5).unwrap();

// Creating a new config struct with our data struct
let mut config = Config::new("./config/myconfig.json5", data).unwrap();
// Load from the file
data.load("test/myconfig.json5", Format::JSON5).unwrap();

// Read/writing to the data
println!("I am ${} in debt", config.data.student_debt);
config.data.student_debt = i32::MAX;
println!("Oh no, i am now ${} in debt!!", config.data.student_debt);
// Read/write to the data
println!("I am {}$ in debt", data.student_debt);
data.student_debt = i32::MAX;
println!("Oh no, i am now {}$ in debt!!", data.student_debt);

// Saving it back to the disk
config.save().unwrap();
}
// Save it back to disk
data.save("test/myconfig.json5", Format::JSON5).unwrap();
```

## Getting started
### Creating Config from File

```rust
let data = MyData::new("example_config.json", Format::JSON).unwrap();
```

1. Add the crate to your project via <br/> `cargo add fast_config`
- Additionally, also add `serde` as it is required!
### String Serialization

2. Enable the feature(s) for the format(s) you'd like to use <br/>
- Currently only `json5`, `toml`, and `yaml` are supported <br/>
```rust
// Convert config to string
let json_string = data.to_string(Format::JSON).unwrap();
let pretty_json = data.to_string_pretty(Format::JSON).unwrap();

// Create config from string
let loaded = MyData::from_string(&json_string, Format::JSON).unwrap();
```

3. Create a struct to hold your data that derives `Serialize` and `Deserialize`
### Pretty Formatting

4. Create an instance of your data struct
- Optionally `use` the crate's `Config` type for convenience: `use fast_config::Config;`
```rust
// Saves in a format thats indented and human-readable
data.save_pretty("config.json", Format::JSON).unwrap();
```

## Getting started

1. Add the crate to your project:
```bash
cargo add fast_config
```
- Also add `serde` with derive features:
```bash
cargo add serde --features derive
```

2. Enable the feature(s) for the format(s) you'd like to use in your `Cargo.toml`:
```toml
[dependencies]
fast_config = { version = "...", features = ["json", "json5", "toml", "yaml", "derive"] }
```
- Available formats: `json`, `json5`, `toml`, `yaml`
- Enable the `derive` feature to use the `#[derive(FastConfig)]` macro

3. Create a struct to hold your data and derive the necessary traits:
```rust
use serde::Serialize;
use serde::Deserialize;
use fast_config::FastConfig;

#[derive(Serialize, Deserialize, FastConfig)]
pub struct MyConfig {
pub setting: String,
}
```

5. To create and store your config file(s), use:
```rust,ignore
let my_config = Config::new("./path/to/my_config_file", your_data).unwrap();
4. Use the trait methods directly on your struct:
```rust
let mut config = MyConfig { setting: "default".into() };
let config_path = "example_getting_started.json";
config.save(config_path, Format::JSON).unwrap();
config.setting = "something else";
config.load(config_path, Format::JSON).unwrap();
```
Alternatively, you can use `Config::from_settings` to style some things and manually set the format!

---

View the [examples](./examples) directory for more advanced examples.
## API Reference

### The `FastConfig` Trait

The `FastConfig` trait provides methods for loading, saving, and serializing config data. When you derive `FastConfig` on your struct, these methods become available:

#### File Operations

- **`load(path, format)`** - Loads config data from a file, replacing the current struct's values
- **`save(path, format)`** - Saves config data to a file (compact format)
- **`save_pretty(path, format)`** - Saves config data to a file with pretty formatting (indented, readable)

#### String Operations

- **`from_string(content, format)`** - Creates a new config instance from a string
- **`to_string(format)`** - Converts config to a compact string representation
- **`to_string_pretty(format)`** - Converts config to a pretty-formatted string

#### Constructor

- **`new(path, format)`** - Creates a new config instance by loading from a file path

### The `#[derive(FastConfig)]` Macro

The derive macro automatically implements the `FastConfig` trait for your struct. It requires that your struct also derives `Serialize` and `Deserialize` from the [`serde`](https://crates.io/crates/serde) crate.

#### Custom Crate Path

If you're re-exporting `fast_config` under a different name, you can specify the crate path:

```rust
use serde::Serialize;
use serde::Deserialize;
use fast_config::FastConfig;

#[derive(Serialize, Deserialize, FastConfig)]
#[fast_config(crate = "my_crate::fast_config")]
pub struct MyConfig {
pub value: i32,
}
```

---

## NOTE: This project will be rewritten sometime
The code is currently very messy, but I'm too busy with other projects to deal with it. </br>
I've improved a lot as a Rust developer since the creation of this project and a lot of the ways you interface with it could be better.
View the [tests](./fast_config/src/tests/) directory for more advanced examples.

Some things I want to do for the rewrite are listed in a comment at the top of [lib.rs](./src/lib.rs)
Some other ideas I'll have to experiment with:
- Moving to a trait-based approach where you can slap a `#[derive(FastConfig)]` onto any struct to give it the `save`/`load` functions.
This makes the annoying `my_config.data.my_setting` into simply `my_config.my_setting`
## Migration Note

A conversion guide for the rewrite will be available, as I'll have to convert over my projects as well to use the rewritten `fast_config`.
The crate now uses a trait-based approach with `#[derive(FastConfig)]`. This makes the API cleaner and more ergonomic - you can now call `save()` and `load()` directly on your config struct instead of wrapping it in a `Config` type.

The rewrite should be smaller, safer, and the source code will most importantly be ***way more readable***.
If you're migrating from an older version, see the [conversion tutorial](./CONVERSION_TUTORIAL.md) for guidance.

---
<br/>
79 changes: 0 additions & 79 deletions examples/advanced.rs

This file was deleted.

29 changes: 0 additions & 29 deletions examples/simple.rs

This file was deleted.

Loading