pavex/blueprint/
prebuilt.rs

1use pavex_bp_schema::{Blueprint as BlueprintSchema, Component, PrebuiltType};
2
3use crate::blueprint::{CloningPolicy, conversions::cloning2cloning};
4
5use super::reflection::AnnotationCoordinates;
6
7/// The input type for [`Blueprint::prebuilt`].
8///
9/// Check out [`Blueprint::prebuilt`] for more information on prebuilt types
10/// in Pavex.
11///
12/// # Stability guarantees
13///
14/// Use the [`prebuilt`](macro@crate::prebuilt) attribute macro to create instances of `Prebuilt`.\
15/// `Prebuilt`'s fields are an implementation detail of Pavex's macros and should not be relied upon:
16/// newer versions of Pavex may add, remove or modify its fields.
17///
18/// [`Blueprint::prebuilt`]: crate::Blueprint::prebuilt
19pub struct Prebuilt {
20    #[doc(hidden)]
21    pub coordinates: AnnotationCoordinates,
22}
23
24/// The type returned by [`Blueprint::prebuilt`].
25///
26/// It allows you to further configure the behaviour of the registered prebuilt type.
27///
28/// [`Blueprint::prebuilt`]: crate::Blueprint::prebuilt
29pub struct RegisteredPrebuilt<'a> {
30    #[allow(unused)]
31    pub(crate) blueprint: &'a mut BlueprintSchema,
32    /// The index of the registered prebuilt type in the blueprint's `components` vector.
33    #[allow(unused)]
34    pub(crate) component_id: usize,
35}
36
37impl RegisteredPrebuilt<'_> {
38    /// Set the cloning strategy for the output type returned by this constructor.
39    ///
40    /// By default,
41    /// Pavex will **never** try to clone a prebuilt type.
42    /// If the type implements [`Clone`], you can change the default by invoking
43    /// [`clone_if_necessary`](Self::clone_if_necessary): Pavex will clone the prebuilt type if
44    /// it's necessary to generate code that satisfies Rust's borrow checker.
45    pub fn cloning(mut self, strategy: CloningPolicy) -> Self {
46        self.prebuilt().cloning_policy = Some(cloning2cloning(strategy));
47        self
48    }
49
50    /// Set the cloning strategy to [`CloningPolicy::CloneIfNecessary`].
51    /// Check out [`cloning`](Self::cloning) method for more details.
52    pub fn clone_if_necessary(self) -> Self {
53        self.cloning(CloningPolicy::CloneIfNecessary)
54    }
55
56    /// Set the cloning strategy to [`CloningPolicy::NeverClone`].
57    /// Check out [`cloning`](Self::cloning) method for more details.
58    pub fn never_clone(self) -> Self {
59        self.cloning(CloningPolicy::NeverClone)
60    }
61
62    fn prebuilt(&mut self) -> &mut PrebuiltType {
63        let component = &mut self.blueprint.components[self.component_id];
64        let Component::PrebuiltType(s) = component else {
65            unreachable!("The component should be a prebuilt type")
66        };
67        s
68    }
69}