Skip to content

Prebuilt types

A prebuilt type is a type that Pavex expects you to provide.
Whenever your mark a type as prebuilt, you're telling Pavex: "I'll build this type on my own, and then pass an instance over to you". In particular, you'll be passing that instance to build_application_state, the function that Pavex generates to build the ApplicationState type.

Registration

To mark a type as prebuilt, you must invoke the prebuilt method on your Blueprint:

src/base/blueprint.rs
// [...]
pub fn blueprint() -> Blueprint {
    let mut bp = Blueprint::new();
    bp.prebuilt(t!(super::A));
    // [...]
}

You must provide an unambiguous path to the type, wrapped in the t! macro.

t! vs f!

t! stands for "type". It isn't f!, the macro used to register function-like components, like constructors or middlewares.
If you mix them up, Pavex will return an error.

The signature changes

Whenever you mark a type as prebuilt, the signature of the code-generated build_application_state function will change to include that type as an input parameter.
In the generated server SDK for the example in the previous section, the signature of build_application_state will change to:

server_sdk/src/lib.rs
// [...]
pub async fn build_application_state(v0: di_prebuilt::base::A) -> crate::ApplicationState {
// [...]
}

Since the signature of build_application_state changes, the calling code in your server crate will have to change accordingly. This may be surprising at first, since you don't often touch the code inside the server crate, but it's entirely expected. Don't worry: you just have to follow the compiler's suggestions to get back on track.

Immutability

The only crate you're never supposed to modify is the server SDK crate, the one that Pavex generates for you. The server crate, on the other hand, is yours to modify as you see fit.

Lifecycle

If a prebuilt input is only needed to construct singletons, it'll be discarded after build_application_state returns.

If it's needed to process requests (e.g. as an input for a middleware), it'll be added as a field to ApplicationState. In this case, Pavex will treat it as a singleton and require it to implement the Send and Sync traits.