# toml_const
TOML compile-time constants
## Getting started
Add these in your `Cargo.toml` file:
```toml
build = "build.rs"
[[bin]]
name = "toml_const_gen"
path = "src/toml_const_gen.rs"
[dependencies]
toml = "0.8"
lazy_static = "1.4"
toml_const = { git = "https://github.com/cruzerngz/toml_const.git" }
[build-dependencies]
toml_const = { git = "https://github.com/cruzerngz/toml_const.git" }
# crate not published on crates.io yet!
# toml_const = "0.1"
```
Create a new binary file `src/toml_const_gen.rs` with the following code:
```rust
use std::process::ExitCode;
use toml_const::cli;
fn main() -> ExitCode {
// use a logging library of your choice
pretty_env_logger::init();
cli::run()
}
```
Run the binary. MANIFEST_PATH is the path to your Cargo.toml package manifest:
```sh
# run "cargo run... -- init --help" to see more arguments
cargo run --bin toml_const_gen -- init <MANIFEST_PATH>
```
The binary will create and configure some files.
Create a build script, `build.rs`, in the same directory as Cargo.toml:
```rust
// build.rs code
fn main() {
toml_const::run();
// ... rest of your build script
}
```
Your package should now look like this:
```sh
package
├── build.rs
├── Cargo.toml
├── .cargo # generated/modified by CLI
│ └── config.toml
├── .config # generated by CLI
│ ├── .gitignore
│ ├── package.debug.toml # debug variant
│ ├── package.deploy.toml # deploy/release variant
│ └── package.template.toml # defaults
├── generated.rs # generated by build.rs
├── .gitignore
└── src
├── main.rs
└── toml_const_gen.rs
```
The generated file `generated.rs` can now be included into your code:
```rust
include!("../generated.rs") // include in main
```
It is recommended include this file in a separate module:
```rust
// inside main.rs / lib.rs
mod consts;
// inside consts.rs
#![allow(unused)]
include!("../generated.rs")
```
And then use it:
```rust
let this = consts::USE; // the USE const must always be defined
```
## Usage
All valid TOML datatypes are generated as compile-time constants, except for arrays and tables.
Arrays and tables are defined inside a `lazy_static!` wrapper.
All tables are destructured, when possible, to keys that point to their TOML values. Namespaces are separated with an underscore "`_`".
For example, this:
```toml
[table]
field = "string"
time = 11:20:00
integer = 3
[table.inner]
field = "another string"
datetime = 1979-05-27 07:32:00Z
one_billion = 1e09
```
Turns to this:
```rust
// ...imports excluded
/// type: i64
pub const TABLE_INTEGER: i64 = (3_i64);
/// type: f64
pub const TABLE_INNER_ONE_BILLION: f64 = (1000000000_f64);
/// type: &'static str
pub const TABLE_INNER_FIELD: &'static str = "another string";
/// type: Datetime
pub const TABLE_TIME: Datetime = Datetime {
date: None,
time: Some(Time {
hour: 11,
minute: 20,
second: 0,
nanosecond: 0,
}),
offset: None,
};
/// type: &'static str
pub const TABLE_FIELD: &'static str = "string";
/// type: Datetime
pub const TABLE_INNER_DATETIME: Datetime = Datetime {
date: Some(Date {
year: 1979,
month: 5,
day: 27,
}),
time: Some(Time {
hour: 7,
minute: 32,
second: 0,
nanosecond: 0,
}),
offset: Some(Offset::Z),
};
```
Toml key `table.time` is is converted to `TABLE_TIME`.
A nested table value `table.inner.one_billion` is destructured to `TABLE_INNER_ONE_BILLION`.
Additionally, last-level tables, or tables that do not contain inner tables or arrays, also have their key-value pairs stored as a `HashMap<&'static str, String>`:
```rust
// `table` contains the `inner` table
// so it is not a last-level table.
//
// HashMaps and arrays are wrapped in lazy_static!{...}
/// type: HashMap<&'static str, String>
pub static ref TABLE_INNER: HashMap<&'static str, String> = HashMap::from([
(
"DATETIME",
Datetime {
date: Some(Date {
year: 1979,
month: 5,
day: 27,
}),
time: Some(Time {
hour: 7,
minute: 32,
second: 0,
nanosecond: 0,
}),
offset: Some(Offset::Z),
}
.to_string(),
),
("FIELD", "another string".to_string()),
("ONE_BILLION", (1000000000_f64).to_string()),
]);
```
This might be useful when iterating over unknown key-value pairs during runtime. You do lose type information, though.
### Template, debug, deploy
`toml_const` generates 3 toml files into your root project directory.
The contents from `*.template.toml` is used as a base, matching keys from
`*.debug.toml` **or** `*.deploy.toml` will override the template values.
Setting the top-level key `use=true` will cause `toml_const`
to generate code from that particular config file.
| `false` | `false` | template: compilation warning |
| `false` | `true` | template + deploy |
| `true` | `false` | template + debug |
| `true` | `true` | template + deploy |