Project Setup
Cargo
Add lockjaw to the [dependencies]
and [build_dependencies]
section of your Cargo.toml
:
[dependencies]
lockjaw = "*"
[build-dependencies]
lockjaw = "*"
The proc_macro and runtime library are packaged into the same crate, so this is the only target you
need. While the proc_macro
library is heavy, Rust should be able to optimize them away in the
resulting binary. The runtime is pretty light, and the generated code is supposed to be zero cost
abstraction.
Build script
Lockjaw also needs some environment setup, and requires a
build script. Add build.rs
next to
Cargo.toml
, and
call lockjaw::build_script()
in main()
inside it:
// https://github.com/azureblaze/lockjaw/tree/main/userguide/projects/setup/build.rs
fn main() {
lockjaw::build_script();
}
Lockjaw will ask you to do this if this step is missing.
Prologue macro
Before using any Lockjaw attribute macros, the
lockjaw prologue!()
macro must be
called:
// https://github.com/azureblaze/lockjaw/tree/main/userguide/projects/setup/src/main.rs
lockjaw::prologue!("src/main.rs");
The file path of the current source file should be passed to the prologue.
Lockjaw need to perform some static analysis on the current source file to understand type names,
which is an integral part of a dependency injection framework. If a type is encountered, what is its
fully qualified name? Is it something imported with a use
declaration? or if it is a locally
declared, what is the mod
path to the local scope?
Lockjaw also generates a test to verify the source path is correct. However passing a wrong path often result in weird type resolution errors at compile time. Double-check the source path if there are type resolution issues.
Epilogue macro
You also must call
the lockjaw::epilogue!()
macro in the
root of your crate (lib.rs
or
main.rs
) after all other uses of lockjaw, preferably at the end of the file.
// https://github.com/azureblaze/lockjaw/tree/main/userguide/projects/setup/src/main.rs
lockjaw::epilogue!();
Source of this chapter