diff --git a/Justfile b/Justfile index 742e59a..fb840b2 100644 --- a/Justfile +++ b/Justfile @@ -27,6 +27,7 @@ fmt: linkcheck: cd book && just build lychee --cache --max-cache-age 7d \ + --exclude https://github\.com/dnaka91/stef \ 'book/src/**/*.md' \ 'book/book/**/*.html' \ 'crates/**/*.rs' diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index 7693ad5..fb2b807 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -10,17 +10,17 @@ # User Guide -- [Installation]() -- [Creating schemas]() -- [Generating code]() +- [Installation](guide/installation.md) +- [Creating schemas](guide/creating.md) +- [Generating code](guide/generating.md) - [Examples](guide/examples.md) # Reference Guide - [Command Line Interface]() - - [init]() - - [check]() - - [format]() + - [stef init]() + - [stef check]() + - [stef format]() - [Schema](schema/index.md) - [Structs](schema/structs.md) - [Enums](schema/enums.md) diff --git a/book/src/guide/creating.md b/book/src/guide/creating.md index 9d996b2..d677efe 100644 --- a/book/src/guide/creating.md +++ b/book/src/guide/creating.md @@ -1,3 +1,28 @@ # Creating schemas + +Basic types + +- Signed integers: `i8`, `i16`, `i32`, `i64` and `i128`. +- Unsigned integers: `u8`, `u16`, `u32`, `u64` and `u128`. +- Floating point numbers: `f32` and `f64`. +- Strings: `string`. +- Bytes: `bytes`. + +Colletions + +- Vectors: `vec`. +- Hash maps: `hash_map`. +- Hash sets: `hash_set`. + +Special types + +- Optionals: `option`. +- Non-zero: `non_zero`. +- Boxed strings: `box`. + +```rust,ignore +{{#include creating/basic.stef}} +``` diff --git a/book/src/guide/creating/basic.stef b/book/src/guide/creating/basic.stef new file mode 100644 index 0000000..ecd55ac --- /dev/null +++ b/book/src/guide/creating/basic.stef @@ -0,0 +1,7 @@ +/// Basic user information. +struct User { + /// Full name of the user. + name: string @1, + /// Current age in years. + age: u16 @2, +} diff --git a/book/src/guide/generating.md b/book/src/guide/generating.md index 84ba8a2..56488bc 100644 --- a/book/src/guide/generating.md +++ b/book/src/guide/generating.md @@ -1,3 +1,72 @@ # Generating code + +## Rust + +First, make sure you followed the [installation](./installation.md#rust) instructions, to setup the dependencies in your _Cargo.toml_ properly. + +The main entry point is the `stef-build` crate, which you use as build script in your `build.rs` file. A basic setup looks like this, assuming you have a single schema under `src/sample.stef`: + +```rust +fn main() { + stef_build::compile(&["src/sample.stef"], &["src/"]).unwrap(); +} +``` + +This will take care of reading and parsing the schema files, then generate the Rust code from them. The code is stored in your `target` folder in a folder specifically for build script output. + +In your code you then include the generated files with Rust's `include!` macro. The correct folder can be accessed through the `OUT_DIR` environment variable and combined with the right file name to get the correct path. + +Continuing on the previous example, the generated could could be included like this: + +```rust +// in src/main.rs + +mod sample { + include!(concat!(env!("OUT_DIR"), "/sample.rs")); +} + +fn main() { + println!("Hello, World!"); +} +``` + +The file name is the same as the input schema file name, but with `.rs` as file extension instead of `.stef`. The schema file `sample.stef` becomes `sample.rs`. + +### Using the code + +From that point on, the generated code can be used like regular Rust code. Extending the example a bit, let's say the schema file contained the following: + +```rust,ignore +struct Sample { + value: u32 @1, +} +``` + +Then we could use the generated struct as follows: + +```rust,ignore +// Include stef's `Encode` trait to get access to the `encode()` method. +use stef::Encode; + +mod sample { + include!(concat!(env!("OUT_DIR"), "/sample.rs")); +} + +fn main() { + // Let's create an instance of your `Sample` struct. + let value = sample::Sample { + value: 5 + }; + + // We can print it out like an Rust value that implements `Debug`: + println!("{value:?}"); + + // Here we encode it into the wire format. + // - byte 1 for the field identifier. + // - byte 5 for the actual value. + // - byte 0 to mark the end of the struct. + assert_eq!(&[1, 5, 0], value.encode()); +} +``` diff --git a/book/src/guide/installation.md b/book/src/guide/installation.md index 0071ad7..d167055 100644 --- a/book/src/guide/installation.md +++ b/book/src/guide/installation.md @@ -1,3 +1,38 @@ # Installation + +## Command Line Interface + +The CLI tool is not strictly needed to compile and use STEF schemas, but it contains several helpful elements like a validator for schema correctness, a formatter and helper for setting up STEF in your project. + +### From source + +Currently it can only be installed from source, using Cargo: + +```sh +cargo install --git https://github.com/dnaka91/stef.git stef-cli +``` + +## Rust + +For Rust projects, two crates are needed to work with STEF schemas and data. One is the `stef` crate for runtime support, which contains all components that are used by the generated code. + +The other one is the `stef-build` crate which generates the Rust code from schema files. It is used as [Build Script](https://doc.rust-lang.org/cargo/reference/build-scripts.html) usually in the _build.rs_ file of your project. + +You can use Cargo's [add](https://doc.rust-lang.org/cargo/commands/cargo-add.html) command to add those dependencies: + +```sh +cargo add --git https://github.com/dnaka91/stef.git stef +cargo add --git https://github.com/dnaka91/stef.git --build stef-build +``` + +Or specify them in your _Cargo.toml_ manually: + +```toml +[dependencies] +stef = { git = "https://github.com/dnaka91/stef.git" } + +[build-dependencies] +stef-build = { git = "https://github.com/dnaka91/stef.git" } +```