pavex/
lib.rs

1#![cfg_attr(docsrs, feature(doc_cfg))]
2//! # Pavex - API reference
3//!
4//! Welcome to the API reference for Pavex!
5//!
6//! The API reference is fairly low-level.\
7//! If you want a high-level overview of Pavex, check out the [documentation](https://pavex.dev/docs/)
8//! on Pavex's website.\
9//! You'll also find [an installation guide](https://pavex.dev/docs/getting_started/) as well as a
10//! [quickstart tutorial](https://pavex.dev/docs/getting_started/quickstart/)
11//! to get you up and running with the framework in no time.
12
13pub use error::error_::Error;
14
15pub use blueprint::blueprint::Blueprint;
16pub use response::{into_response::IntoResponse, response_::Response};
17
18pub mod blueprint;
19#[cfg(feature = "config")]
20#[cfg_attr(docsrs, doc(cfg(feature = "config")))]
21pub mod config;
22pub mod connection;
23#[cfg(feature = "cookie")]
24#[cfg_attr(docsrs, doc(cfg(feature = "cookie")))]
25pub mod cookie;
26pub mod error;
27pub mod http;
28pub mod middleware;
29pub mod request;
30pub mod response;
31pub mod router;
32pub mod serialization;
33#[cfg(feature = "server")]
34#[cfg_attr(docsrs, doc(cfg(feature = "server")))]
35pub mod server;
36pub mod telemetry;
37pub mod unit;
38#[cfg(feature = "time")]
39#[cfg_attr(docsrs, doc(cfg(feature = "time")))]
40pub mod time {
41    //! Utilities to work with dates, timestamps and datetimes.
42    //!
43    //! It's a re-export of the [`[email protected]`](https://docs.rs/jiff/0.2) crate.
44    pub use jiff::*;
45}
46pub mod tls;
47
48/// Define a [prebuilt type](https://pavex.dev/docs/guide/dependency_injection/prebuilt_types/).
49///
50/// Prebuilt types are constructed outside of Pavex's dependency injection framework
51/// but can still be injected as dependencies into your components.
52///
53/// # Example
54///
55/// ```rust
56/// use pavex::prebuilt;
57///
58/// #[prebuilt]
59/// #[derive(Debug)]
60/// pub struct DatabaseConnectionPool {
61///     // Connection pool initialized elsewhere
62/// }
63/// ```
64///
65/// # Guide
66///
67/// Check out the ["Dependency injection"](https://pavex.dev/docs/guide/dependency_injection)
68/// section of Pavex's guide for a thorough introduction to dependency injection
69/// in Pavex applications.
70///
71/// # Registration
72///
73/// You can register a prebuilt type with your application in two ways:
74/// - Use [`Blueprint::prebuilt`] to register a single prebuilt type
75/// - Use [`Blueprint::import`] to import multiple prebuilt types in bulk
76///
77/// The `#[prebuilt]` macro [generates a constant](#id) that you can use to refer to a specific
78/// prebuilt type when invoking [`Blueprint::prebuilt`].
79///
80/// # Arguments
81///
82/// The sections below provide an exhaustive list of all the arguments and flags supported by the [`prebuilt`][macro@prebuilt] macro:
83///
84/// | Name                                          | Kind     | Required |
85/// |-----------------------------------------------|----------|----------|
86/// | [`id`](#id)                                   | Argument | No       |
87/// | [`clone_if_necessary`](#clone_if_necessary)   | Flag     | No       |
88/// | [`never_clone`](#never_clone)                 | Flag     | No       |
89/// | [`allow`](#allow)                             | Argument | No       |
90///
91/// ## `id`
92///
93/// When using [`Blueprint::prebuilt`], Pavex generates a constant named after your type
94/// (converted to UPPER_SNAKE_CASE) that you use to refer to the prebuilt type.
95///
96/// The `id` argument allows you to customize the name of the generated constant.
97///
98/// ### Example
99///
100/// ```rust
101/// use pavex::{prebuilt, Blueprint};
102///
103/// #[prebuilt(id = "DB_POOL")]
104/// //         πŸ‘† Custom identifier
105/// #[derive(Debug)]
106/// pub struct DatabaseConnectionPool {
107///     // [...]
108/// }
109///
110/// # fn main() {
111/// let mut bp = Blueprint::new();
112/// // Use the custom identifier when registering
113/// bp.prebuilt(DB_POOL);
114/// # }
115/// ```
116///
117/// ## `clone_if_necessary`
118///
119/// By default, Pavex will **not** clone prebuilt types. The `clone_if_necessary` flag
120/// allows Pavex to invoke `.clone()` on the type if it helps satisfy Rust's borrow checker.
121///
122/// The prebuilt type must implement the `Clone` trait.
123///
124/// This flag is mutually exclusive with `never_clone`.
125///
126/// ### Example
127///
128/// ```rust
129/// use pavex::prebuilt;
130///
131/// #[prebuilt(clone_if_necessary)]
132/// //         πŸ‘† Allow cloning when needed
133/// #[derive(Debug, Clone)]
134/// pub struct DatabaseConnectionPool {
135///     // [...]
136/// }
137/// ```
138///
139/// ## `never_clone`
140///
141/// The `never_clone` flag explicitly prevents Pavex from cloning the prebuilt type.
142/// This is the default behavior for prebuilt types, so this flag is typically used
143/// for clarity and explicitness.
144///
145/// This flag is mutually exclusive with `clone_if_necessary`.
146///
147/// ### Example
148///
149/// ```rust
150/// use pavex::prebuilt;
151///
152/// #[prebuilt(never_clone)]
153/// //         πŸ‘† Explicitly prevent cloning (default behavior)
154/// #[derive(Debug)]
155/// pub struct NonCloneableResource {
156///     // Some resource that shouldn't be cloned
157///     file_handle: std::fs::File,
158/// }
159/// ```
160///
161/// Pavex will report an error during the code-generation phase if cloning is required
162/// but forbidden.
163///
164/// ## `allow`
165///
166/// The `allow` argument can be used to suppress specific warnings.
167///
168/// Currently, only one value is supported:
169/// - `unused`: Suppress warnings if this prebuilt type is registered but never used
170///
171/// ### Example
172///
173/// ```rust
174/// use pavex::prebuilt;
175///
176/// #[prebuilt(allow(unused))]
177/// //         πŸ‘† Don't warn if unused
178/// #[derive(Debug, Clone)]
179/// pub struct DatabaseConnectionPool {
180///     // [...]
181/// }
182/// ```
183///
184/// [`Blueprint::import`]: crate::Blueprint::import
185/// [`Blueprint::prebuilt`]: crate::Blueprint::prebuilt
186pub use pavex_macros::prebuilt;
187
188/// Define a [configuration type](https://pavex.dev/docs/guide/configuration/).
189///
190/// # Example
191///
192/// ```rust
193/// use pavex::config;
194///
195/// #[config(key = "pool")]
196/// #[derive(serde::Deserialize, Debug, Clone)]
197/// pub struct PoolConfig {
198///     pub max_n_connections: u32,
199///     pub min_n_connections: u32,
200/// }
201/// ```
202///
203/// # Guide
204///
205/// Check out the ["Configuration"](https://pavex.dev/docs/guide/configuration/)
206/// section of Pavex's guide for a thorough introduction to configuration
207/// in Pavex applications.
208///
209/// # Import
210///
211/// Use [`Blueprint::config`] or [`Blueprint::import`] to add the newly-defined configuration type
212/// to your application.
213///
214/// # Arguments
215///
216/// The sections below provide an exhaustive list of all the arguments and flags supported by the [`config`][macro@config] macro:
217///
218/// | Name                                        | Kind     | Required |
219/// |---------------------------------------------|----------|----------|
220/// | [`key`](#key)                               | Argument | Yes      |
221/// | [`default_if_missing`](#default_if_missing) | Flag     | No       |
222/// | [`include_if_unused`](#include_if_unused)   | Flag     | No       |
223/// | [`never_clone`](#never_clone)               | Flag     | No       |
224///
225/// ## `key`
226///
227/// The `config` macro expects a `key` argument.\
228/// `key` will be used as the name of the corresponding field in the
229/// [generated `ApplicationConfig` struct][`ApplicationConfig`].
230///
231/// The provided key must satisfy a few constraints:
232///
233/// - It can't be empty.
234/// - It must start with a letter.
235/// - It can only contain letters, numbers, and underscores.
236/// - It must be unique within the application.
237///
238/// ### Example
239///
240/// ```rust
241/// use pavex::config;
242///
243/// #[config(key = "pool")]
244/// //       πŸ‘† The key for this configuration type.
245/// #[derive(serde::Deserialize, Debug, Clone)]
246/// pub struct PoolConfig {
247///     pub max_n_connections: u32,
248///     pub min_n_connections: u32,
249/// }
250/// ```
251///
252/// ## `default_if_missing`
253///
254/// By default, Pavex considers all configuration types to be **required**.
255/// There **must** be a value for each configuration key in the source we're reading fromβ€”e.g. a
256/// YAML configuration file. If a key is missing, Pavex will return an error.
257///
258/// The `default_if_missing` flag disables this behaviour.
259/// Pavex will invoke [`Default::default()`][`std::default::Default::default`] to provide a default
260/// value if the configuration key was omitted by the configuration source. No error will be raised.
261///
262/// `default_if_missing` can only be used on types that implement the [`Default`] trait.
263///
264/// ### Example
265///
266/// Consider the following configuration type:
267///
268/// ```rust
269/// use pavex::config;
270///
271/// #[config(key = "pool", default_if_missing)]
272/// //                     πŸ‘† The flag
273/// #[derive(serde::Deserialize, Debug, Clone)]
274/// pub struct PoolConfig {
275///     pub max_n_connections: u32,
276///     pub min_n_connections: u32,
277/// }
278///
279/// impl Default for PoolConfig {
280///     fn default() -> Self {
281///         Self {
282///             max_n_connections: 10,
283///             min_n_connections: 2,
284///         }
285///     }
286/// }
287/// ```
288///
289/// The definition of `ApplicationConfig`, in the generated server SDK code, will look like this:
290///
291/// ```rust
292/// # #[derive(Debug, Clone, Default, serde::Deserialize)]
293/// # struct PoolConfig {}
294/// #[derive(serde::Deserialize, Debug, Clone)]
295/// pub struct ApplicationConfig {
296///     #[serde(default)]
297///     // πŸ‘† Tell `serde` to use the default value
298///     //    if the field is missing.
299///     pub pool: PoolConfig,
300///     // [..other config types..]
301/// }
302/// ```
303///
304///
305/// Therefore, given this YAML configuration file as input,
306///
307/// ```yaml
308/// tls:
309///   enabled: true
310/// # No `pool` entry!
311/// ```
312///
313/// Pavex will initialize `PoolConfig` using its default values, rather than returning an error.
314///
315/// ## `include_if_unused`
316///
317/// By default, Pavex will prune unused configuration types from the
318/// final [`ApplicationConfig` type][`ApplicationConfig`].
319///
320/// The `include_if_unused` flag disables this behaviour.
321/// There will always be an entry in [`ApplicationConfig`] for configuration types
322/// marked as `include_if_unused`, even if their value is never accessed by any constructor,
323/// route, or middleware.
324///
325/// ### Example
326///
327/// Consider this configuration type:
328///
329/// ```rust
330/// use pavex::config;
331///
332/// #[config(key = "pool", include_if_unused)]
333/// //                     πŸ‘† The flag
334/// #[derive(serde::Deserialize, Debug, Clone)]
335/// pub struct PoolConfig {
336///     pub max_n_connections: u32,
337///     pub min_n_connections: u32,
338/// }
339/// ```
340///
341/// The resulting `ApplicationConfig` will *always* contain an entry for `PoolConfig`,
342/// even if it's never used. In the generated server SDK code:
343///
344/// ```rust
345/// # #[derive(Debug, Clone, serde::Deserialize)]
346/// # struct PoolConfig {}
347/// #[derive(Debug, Clone, serde::Deserialize)]
348/// pub struct ApplicationConfig {
349///     pub pool: PoolConfig,
350///     // πŸ‘† You'll always find this field.
351///
352///     // [..other config types..]
353/// }
354/// ```
355///
356/// ## `never_clone`
357///
358/// By default, Pavex will invoke `.clone()` on configuration types if it helps to satisfy
359/// Rust's borrow checker.
360///
361/// The `never_clone` flag disables this behaviour:
362///
363/// ```rust
364/// use pavex::config;
365///
366/// #[config(key = "pool", never_clone)]
367/// //                     πŸ‘† The flag
368/// #[derive(serde::Deserialize, Debug)]
369/// pub struct PoolConfig {
370///     pub max_n_connections: u32,
371///     pub min_n_connections: u32,
372/// }
373/// ```
374///
375/// Pavex will report an error during the code-generation phase if cloning is required
376/// but forbidden.
377///
378/// [`Blueprint::import`]: crate::Blueprint::import
379/// [`Blueprint::config`]: crate::Blueprint::config
380/// [`ApplicationConfig`]: https://pavex.dev/docs/guide/configuration/application_config/
381pub use pavex_macros::config;
382
383/// Define a [request-scoped constructor](https://pavex.dev/docs/guide/dependency_injection/constructors/).
384///
385/// Request-scoped constructors are invoked once per request to create a new instance
386/// of their output type. The created instance is cached for the duration of the request
387/// processing lifecycle.
388///
389/// Check out [`#[singleton]`](macro@crate::singleton) and [`#[transient]`](macro@crate::transient)
390/// if you need to define constructors with different lifecycles.
391///
392/// # Example
393///
394/// ```rust
395/// use pavex::methods;
396///
397/// pub struct RequestId(uuid::Uuid);
398///
399/// #[methods]
400/// impl RequestId {
401///     #[request_scoped]
402///     pub fn new() -> Self {
403///         Self(uuid::Uuid::new_v4())
404///     }
405/// }
406/// ```
407///
408/// `RequestId::new` will be called once per request whenever a new instance of
409/// `RequestId` is needed.
410///
411/// # Guide
412///
413/// Check out the ["Dependency injection"](https://pavex.dev/docs/guide/dependency_injection)
414/// section of Pavex's guide for a thorough introduction to dependency injection
415/// in Pavex applications.
416///
417/// # Registration
418///
419/// You can register a request-scoped constructor with your application in two ways:
420/// - Use [`Blueprint::constructor`] to register a single constructor
421/// - Use [`Blueprint::import`] to import multiple constructors in bulk
422///
423/// The `#[request_scoped]` macro [generates a constant](#id) that you can use to refer to the
424/// constructor when invoking [`Blueprint::constructor`].
425///
426/// # Arguments
427///
428/// The sections below provide an exhaustive list of all the arguments and flags supported by the [`request_scoped`][macro@request_scoped] macro:
429///
430/// | Name                                        | Kind     | Required |
431/// |---------------------------------------------|----------|----------|
432/// | [`id`](#id)                                 | Argument | No       |
433/// | [`clone_if_necessary`](#clone_if_necessary) | Flag     | No       |
434/// | [`never_clone`](#never_clone)               | Flag     | No       |
435/// | [`allow`](#allow)                           | Argument | No       |
436///
437/// ## `id`
438///
439/// By default, Pavex generates a constant named after your type and method
440/// (converted to UPPER_SNAKE_CASE) that you use when registering the constructor.
441///
442/// The `id` argument allows you to customize the name of the generated constant.
443///
444/// ### Example
445///
446/// Using the default generated identifier:
447///
448/// ```rust
449/// use pavex::{methods, Blueprint};
450///
451/// pub struct RequestLogger {
452///     // [...]
453/// }
454///
455/// #[methods]
456/// impl RequestLogger {
457///     #[request_scoped]
458///     pub fn new() -> Self {
459///         Self {
460///             // [...]
461///         }
462///     }
463/// }
464///
465/// # fn main() {
466/// let mut bp = Blueprint::new();
467/// // The generated constant is named `REQUEST_LOGGER_NEW`
468/// bp.constructor(REQUEST_LOGGER_NEW);
469/// # }
470/// ```
471///
472/// Using a custom identifier:
473///
474/// ```rust
475/// use pavex::{methods, Blueprint};
476///
477/// pub struct RequestLogger {
478///     // [...]
479/// }
480///
481/// #[methods]
482/// impl RequestLogger {
483///     #[request_scoped(id = "LOGGER_CONSTRUCTOR")]
484///     //               πŸ‘† Custom identifier
485///     pub fn new() -> Self {
486///         Self {
487///             // [...]
488///         }
489///     }
490/// }
491///
492/// # fn main() {
493/// let mut bp = Blueprint::new();
494/// // Use the custom identifier when registering
495/// bp.constructor(LOGGER_CONSTRUCTOR);
496/// # }
497/// ```
498///
499/// ## `clone_if_necessary`
500///
501/// By default, Pavex will **not** clone the output of request-scoped constructors. The `clone_if_necessary`
502/// flag allows Pavex to invoke `.clone()` on the output if it helps satisfy Rust's borrow checker.
503///
504/// The constructed type must implement the `Clone` trait.
505///
506/// This flag is mutually exclusive with `never_clone`.
507///
508/// ### Example
509///
510/// ```rust
511/// use pavex::methods;
512/// use std::collections::HashMap;
513///
514/// #[derive(Clone)]
515/// pub struct RequestConfig {
516///     settings: HashMap<String, String>,
517/// }
518///
519/// #[methods]
520/// impl RequestConfig {
521///     #[request_scoped(clone_if_necessary)]
522///     //               πŸ‘† Allow cloning when needed
523///     pub fn new() -> Self {
524///         Self {
525///             settings: HashMap::new(),
526///         }
527///     }
528/// }
529/// ```
530///
531/// ## `never_clone`
532///
533/// The `never_clone` flag explicitly prevents Pavex from cloning the output of this constructor.
534/// This is the default behavior for request-scoped constructors, so this flag is typically used
535/// for clarity and explicitness.
536///
537/// This flag is mutually exclusive with `clone_if_necessary`.
538///
539/// ### Example
540///
541/// ```rust
542/// use pavex::methods;
543///
544/// pub struct ScratchPad {
545///     // Contains non-cloneable resources
546///     temp_file: std::fs::File,
547/// }
548///
549/// #[methods]
550/// impl ScratchPad {
551///     #[request_scoped(never_clone)]
552///     //               πŸ‘† Explicitly prevent cloning (default behavior)
553///     pub fn new() -> std::io::Result<Self> {
554///         Ok(Self {
555///             temp_file: std::fs::File::create("request.tmp")?,
556///         })
557///     }
558/// }
559/// ```
560///
561/// Pavex will report an error during the code-generation phase if cloning is required
562/// but forbidden.
563///
564/// ## `allow`
565///
566/// The `allow` argument can be used to suppress specific warnings.
567///
568/// Currently, only one value is supported:
569/// - `unused`: Suppress warnings if this constructor is registered but never used
570///
571/// ### Example
572///
573/// ```rust
574/// use pavex::methods;
575///
576/// pub struct DebugInfo {
577///     // [...]
578/// }
579///
580/// #[methods]
581/// impl DebugInfo {
582///     #[request_scoped(allow(unused))]
583///     //               πŸ‘† Don't warn if unused
584///     pub fn new() -> Self {
585///         Self {
586///             // [...]
587///         }
588///     }
589/// }
590/// ```
591///
592/// [`Blueprint::import`]: crate::Blueprint::import
593/// [`Blueprint::constructor`]: crate::Blueprint::constructor
594#[doc(alias = "constructor")]
595pub use pavex_macros::request_scoped;
596
597/// Define a [singleton constructor](https://pavex.dev/docs/guide/dependency_injection/constructors/).
598///
599/// Singleton constructors are invoked once (when the application starts up) to create
600/// a new instance of their output type. The created instance is then shared across all
601/// requests for the lifetime of the application.
602///
603/// Check out [`#[request_scoped]`](macro@crate::request_scoped) and [`#[transient]`](macro@crate::transient)
604/// if you need to define constructors with different lifecycles.
605///
606/// # Example
607///
608/// ```rust
609/// use pavex::methods;
610///
611/// pub struct DatabasePool {
612///     // [...]
613/// }
614///
615/// #[methods]
616/// impl DatabasePool {
617///     #[singleton]
618///     pub fn new() -> Self {
619///         Self {
620///             // [...]
621///         }
622///     }
623/// }
624/// ```
625///
626/// `DatabasePool::new` will be called once at application startup, and the resulting
627/// instance will be shared across all requests.
628///
629/// # Guide
630///
631/// Check out the ["Dependency injection"](https://pavex.dev/docs/guide/dependency_injection)
632/// section of Pavex's guide for a thorough introduction to dependency injection
633/// in Pavex applications.
634///
635/// # Registration
636///
637/// You can register a singleton constructor with your application in two ways:
638/// - Use [`Blueprint::constructor`] to register a single constructor
639/// - Use [`Blueprint::import`] to import multiple constructors in bulk
640///
641/// The `#[singleton]` macro [generates a constant](#id) that you can use to refer to the
642/// constructor when invoking [`Blueprint::constructor`].
643///
644/// # Arguments
645///
646/// The sections below provide an exhaustive list of all the arguments and flags supported by the [`singleton`][macro@singleton] macro:
647///
648/// | Name                                        | Kind     | Required |
649/// |---------------------------------------------|----------|----------|
650/// | [`id`](#id)                                 | Argument | No       |
651/// | [`clone_if_necessary`](#clone_if_necessary) | Flag     | No       |
652/// | [`never_clone`](#never_clone)               | Flag     | No       |
653/// | [`allow`](#allow)                           | Argument | No       |
654///
655/// ## `id`
656///
657/// By default, Pavex generates a constant named after your type and method
658/// (converted to UPPER_SNAKE_CASE) that you use when registering the constructor.
659///
660/// The `id` argument allows you to customize the name of the generated constant.
661///
662/// ### Example
663///
664/// Using the default generated identifier:
665///
666/// ```rust
667/// use pavex::{methods, Blueprint};
668///
669/// pub struct CacheManager {
670///     // [...]
671/// }
672///
673/// #[methods]
674/// impl CacheManager {
675///     #[singleton]
676///     pub fn new() -> Self {
677///         Self {
678///             // [...]
679///         }
680///     }
681/// }
682///
683/// # fn main() {
684/// let mut bp = Blueprint::new();
685/// // The generated constant is named `CACHE_MANAGER_NEW`
686/// bp.constructor(CACHE_MANAGER_NEW);
687/// # }
688/// ```
689///
690/// Using a custom identifier:
691///
692/// ```rust
693/// use pavex::{methods, Blueprint};
694///
695/// pub struct CacheManager {
696///     // [...]
697/// }
698///
699/// #[methods]
700/// impl CacheManager {
701///     #[singleton(id = "CACHE_CONSTRUCTOR")]
702///     //           πŸ‘† Custom identifier
703///     pub fn new() -> Self {
704///         Self {
705///             // [...]
706///         }
707///     }
708/// }
709///
710/// # fn main() {
711/// let mut bp = Blueprint::new();
712/// // Use the custom identifier when registering
713/// bp.constructor(CACHE_CONSTRUCTOR);
714/// # }
715/// ```
716///
717/// ## `clone_if_necessary`
718///
719/// By default, Pavex will **not** clone the output of singleton constructors. The `clone_if_necessary`
720/// flag allows Pavex to invoke `.clone()` on the output if it helps satisfy Rust's borrow checker.
721///
722/// The constructed type must implement the `Clone` trait.
723///
724/// This flag is mutually exclusive with `never_clone`.
725///
726/// ### Example
727///
728/// ```rust
729/// use pavex::methods;
730/// use std::collections::HashMap;
731///
732/// #[derive(Clone)]
733/// pub struct GlobalConfig {
734///     settings: HashMap<String, String>,
735/// }
736///
737/// #[methods]
738/// impl GlobalConfig {
739///     #[singleton(clone_if_necessary)]
740///     //          πŸ‘† Allow cloning when needed
741///     pub fn new() -> Self {
742///         Self {
743///             settings: HashMap::new(),
744///         }
745///     }
746/// }
747/// ```
748///
749/// ## `never_clone`
750///
751/// The `never_clone` flag explicitly prevents Pavex from cloning the output of this constructor.
752/// This is the default behavior for singleton constructors, so this flag is typically used
753/// for clarity and explicitness.
754///
755/// This flag is mutually exclusive with `clone_if_necessary`.
756///
757/// ### Example
758///
759/// ```rust
760/// use pavex::methods;
761///
762/// pub struct LogSink {
763///     // Contains non-cloneable resources
764///     handle: std::fs::File,
765/// }
766///
767/// #[methods]
768/// impl LogSink {
769///     #[singleton(never_clone)]
770///     //          πŸ‘† Explicitly prevent cloning (default behavior)
771///     pub fn new() -> std::io::Result<Self> {
772///         Ok(Self {
773///             handle: std::fs::File::create("global.log")?,
774///         })
775///     }
776/// }
777/// ```
778///
779/// Pavex will report an error during the code-generation phase if cloning is required
780/// but forbidden.
781///
782/// ## `allow`
783///
784/// The `allow` argument can be used to suppress specific warnings.
785///
786/// Currently, only one value is supported:
787/// - `unused`: Suppress warnings if this constructor is registered but never used
788///
789/// ### Example
790///
791/// ```rust
792/// use pavex::methods;
793///
794/// pub struct MetricsCollector {
795///     // [...]
796/// }
797///
798/// #[methods]
799/// impl MetricsCollector {
800///     #[singleton(allow(unused))]
801///     //          πŸ‘† Don't warn if unused
802///     pub fn new() -> Self {
803///         Self {
804///             // [...]
805///         }
806///     }
807/// }
808/// ```
809///
810/// [`Blueprint::import`]: crate::Blueprint::import
811/// [`Blueprint::constructor`]: crate::Blueprint::constructor
812#[doc(alias = "constructor")]
813pub use pavex_macros::singleton;
814
815/// Define a [transient constructor](https://pavex.dev/docs/guide/dependency_injection/constructors/).
816///
817/// Transient constructors are invoked each time a new instance of their output type
818/// is needed, even within the same request. The created instances are not cached.
819///
820/// Check out [`#[singleton]`](macro@crate::singleton) and [`#[request_scoped]`](macro@crate::request_scoped)
821/// if you need to define constructors with different lifecycles.
822///
823/// # Example
824///
825/// ```rust
826/// use pavex::methods;
827///
828/// pub struct TemporaryBuffer {
829///     data: Vec<u8>,
830/// }
831///
832/// #[methods]
833/// impl TemporaryBuffer {
834///     #[transient]
835///     pub fn new() -> Self {
836///         Self {
837///             data: Vec::with_capacity(1024),
838///         }
839///     }
840/// }
841/// ```
842///
843/// `TemporaryBuffer::new` will be called each time a new instance of `TemporaryBuffer` is needed,
844/// even within the same request.
845///
846/// # Guide
847///
848/// Check out the ["Dependency injection"](https://pavex.dev/docs/guide/dependency_injection)
849/// section of Pavex's guide for a thorough introduction to dependency injection
850/// in Pavex applications.
851///
852/// # Registration
853///
854/// You can register a transient constructor with your application in two ways:
855/// - Use [`Blueprint::constructor`] to register a single constructor
856/// - Use [`Blueprint::import`] to import multiple constructors in bulk
857///
858/// The `#[transient]` macro [generates a constant](#id) that you can use to refer to the
859/// constructor when invoking [`Blueprint::constructor`].
860///
861/// # Arguments
862///
863/// The sections below provide an exhaustive list of all the arguments and flags supported by the [`transient`][macro@transient] macro:
864///
865/// | Name                                        | Kind     | Required |
866/// |---------------------------------------------|----------|----------|
867/// | [`id`](#id)                                 | Argument | No       |
868/// | [`clone_if_necessary`](#clone_if_necessary) | Flag     | No       |
869/// | [`never_clone`](#never_clone)               | Flag     | No       |
870/// | [`allow`](#allow)                           | Argument | No       |
871///
872/// ## `id`
873///
874/// By default, Pavex generates a constant named after your type and method
875/// (converted to UPPER_SNAKE_CASE) that you use when registering the constructor.
876///
877/// The `id` argument allows you to customize the name of the generated constant.
878///
879/// ### Example
880///
881/// Using the default generated identifier:
882///
883/// ```rust
884/// use pavex::{methods, Blueprint};
885///
886/// pub struct TokenGenerator {
887///     // [...]
888/// }
889///
890/// #[methods]
891/// impl TokenGenerator {
892///     #[transient]
893///     pub fn new() -> Self {
894///         Self {
895///             // [...]
896///         }
897///     }
898/// }
899///
900/// # fn main() {
901/// let mut bp = Blueprint::new();
902/// // The generated constant is named `TOKEN_GENERATOR_NEW`
903/// bp.constructor(TOKEN_GENERATOR_NEW);
904/// # }
905/// ```
906///
907/// Using a custom identifier:
908///
909/// ```rust
910/// use pavex::{methods, Blueprint};
911///
912/// pub struct TokenGenerator {
913///     // [...]
914/// }
915///
916/// #[methods]
917/// impl TokenGenerator {
918///     #[transient(id = "TOKEN_CONSTRUCTOR")]
919///     //           πŸ‘† Custom identifier
920///     pub fn new() -> Self {
921///         Self {
922///             // [...]
923///         }
924///     }
925/// }
926///
927/// # fn main() {
928/// let mut bp = Blueprint::new();
929/// // Use the custom identifier when registering
930/// bp.constructor(TOKEN_CONSTRUCTOR);
931/// # }
932/// ```
933///
934/// ## `clone_if_necessary`
935///
936/// By default, Pavex will **not** clone the output of transient constructors. The `clone_if_necessary`
937/// flag allows Pavex to invoke `.clone()` on the output if it helps satisfy Rust's borrow checker.
938///
939/// The constructed type must implement the `Clone` trait.
940///
941/// This flag is mutually exclusive with `never_clone`.
942///
943/// ### Example
944///
945/// ```rust
946/// use pavex::{transient, methods};
947/// use uuid::Uuid;
948///
949/// #[derive(Clone)]
950/// pub struct InstanceId {
951///     value: Uuid,
952/// }
953///
954/// #[methods]
955/// impl InstanceId {
956///     #[transient(clone_if_necessary)]
957///     //           πŸ‘† Allow cloning when needed
958///     pub fn new() -> Self {
959///         Self {
960///             value: uuid::Uuid::new_v4(),
961///         }
962///     }
963/// }
964/// ```
965///
966/// ## `never_clone`
967///
968/// The `never_clone` flag explicitly prevents Pavex from cloning the output of this constructor.
969/// This is the default behavior for transient constructors, so this flag is typically used
970/// for clarity and explicitness.
971///
972/// This flag is mutually exclusive with `clone_if_necessary`.
973///
974/// ### Example
975///
976/// ```rust
977/// use pavex::methods;
978///
979/// pub struct TempFile {
980///     // Contains non-cloneable resources
981///     handle: std::fs::File,
982/// }
983///
984/// #[methods]
985/// impl TempFile {
986///     #[transient(never_clone)]
987///     //           πŸ‘† Explicitly prevent cloning (default behavior)
988///     pub fn new() -> std::io::Result<Self> {
989///         Ok(Self {
990///             handle: std::fs::File::create_new("temp.tmp")?,
991///         })
992///     }
993/// }
994/// ```
995///
996/// Pavex will report an error during the code-generation phase if cloning is required
997/// but forbidden.
998///
999/// ## `allow`
1000///
1001/// The `allow` argument can be used to suppress specific warnings.
1002///
1003/// Currently, only one value is supported:
1004/// - `unused`: Suppress warnings if this constructor is registered but never used
1005///
1006/// ### Example
1007///
1008/// ```rust
1009/// use pavex::methods;
1010///
1011/// pub struct TraceId {
1012///     // [...]
1013/// }
1014///
1015/// #[methods]
1016/// impl TraceId {
1017///     #[transient(allow(unused))]
1018///     //           πŸ‘† Don't warn if unused
1019///     pub fn new() -> Self {
1020///         Self {
1021///             // [...]
1022///         }
1023///     }
1024/// }
1025/// ```
1026///
1027/// [`Blueprint::import`]: crate::Blueprint::import
1028/// [`Blueprint::constructor`]: crate::Blueprint::constructor
1029#[doc(alias = "constructor")]
1030pub use pavex_macros::transient;
1031
1032/// Define a [wrapping middleware](https://pavex.dev/docs/guide/middleware/wrapping/).
1033///
1034/// # Example
1035///
1036/// A middleware that applies a timeout to all incoming requests:
1037///
1038/// ```rust
1039/// use pavex::{wrap, middleware::Next, Response};
1040/// use tokio::time::error::Elapsed;
1041///
1042/// #[wrap]
1043/// pub async fn timeout<C>(next: Next<C>) -> Result<Response, Elapsed>
1044/// where
1045///     C: IntoFuture<Output = Response>,
1046/// {
1047///     let max_duration = std::time::Duration::from_secs(20);
1048///     tokio::time::timeout(max_duration, next.into_future()).await
1049/// }
1050/// ```
1051///
1052/// # Guide
1053///
1054/// Check out the ["Middlewares"](https://pavex.dev/docs/guide/middleware/)
1055/// section of Pavex's guide for a thorough introduction to middlewares
1056/// in Pavex applications.
1057///
1058/// # Registration
1059///
1060/// Use [`Blueprint::wrap`] to register the middleware with your [`Blueprint`].
1061///
1062/// The `#[wrap]` macro [generates a constant](#id) that you can use to refer to the
1063/// middleware when invoking [`Blueprint::wrap`].
1064///
1065/// # Arguments
1066///
1067/// The sections below provide an exhaustive list of all the arguments and flags supported by the [`wrap`][macro@wrap] macro:
1068///
1069/// | Name                | Kind     | Required |
1070/// |---------------------|----------|----------|
1071/// | [`id`](#id)         | Argument | No       |
1072///
1073/// ## `id`
1074///
1075/// By default, Pavex generates a constant named after your function
1076/// (converted to UPPER_SNAKE_CASE) that you use when registering the middleware.
1077///
1078/// The `id` argument allows you to customize the name of the generated constant.
1079///
1080/// ### Example
1081///
1082/// Using the default generated identifier:
1083///
1084/// ```rust
1085/// use pavex::{wrap, Blueprint, middleware::Next, Response};
1086/// use tokio::time::error::Elapsed;
1087///
1088/// #[wrap]
1089/// pub async fn timeout<C>(next: Next<C>) -> Result<Response, Elapsed>
1090/// where
1091///     C: IntoFuture<Output = Response>,
1092/// {
1093///     let max_duration = std::time::Duration::from_secs(20);
1094///     tokio::time::timeout(max_duration, next.into_future()).await
1095/// }
1096///
1097/// # fn main() {
1098/// let mut bp = Blueprint::new();
1099/// bp.wrap(TIMEOUT);
1100/// # }
1101/// ```
1102///
1103/// Using a custom identifier:
1104///
1105/// ```rust
1106/// use pavex::{wrap, Blueprint, middleware::Next, Response};
1107/// use tokio::time::error::Elapsed;
1108///
1109/// #[wrap(id = "MY_TIMEOUT")]
1110/// //     πŸ‘† Custom identifier
1111/// pub async fn timeout<C>(next: Next<C>) -> Result<Response, Elapsed>
1112/// where
1113///     C: IntoFuture<Output = Response>,
1114/// {
1115///     let max_duration = std::time::Duration::from_secs(20);
1116///     tokio::time::timeout(max_duration, next.into_future()).await
1117/// }
1118///
1119/// # fn main() {
1120/// let mut bp = Blueprint::new();
1121/// // Use the custom identifier when registering
1122/// bp.wrap(MY_TIMEOUT);
1123/// # }
1124/// ```
1125///
1126/// [`Blueprint::wrap`]: crate::Blueprint::wrap
1127/// [`Blueprint`]: crate::Blueprint
1128#[doc(alias = "middleware")]
1129pub use pavex_macros::wrap;
1130
1131/// Define a [pre-processing middleware](https://pavex.dev/docs/guide/middleware/pre_processing/).
1132///
1133/// # Example
1134///
1135/// Redirect requests to paths that end with a trailing `/` to
1136/// the equivalent path without the trailing `/`:
1137///
1138/// ```rust
1139/// use pavex::{pre_process, http::{HeaderValue, header::LOCATION}};
1140/// use pavex::middleware::Processing;
1141/// use pavex::request::RequestHead;
1142/// use pavex::Response;
1143///
1144/// #[pre_process]
1145/// pub fn redirect_to_normalized(head: &RequestHead) -> Processing {
1146///     let Some(normalized_path) = head.target.path().strip_suffix('/') else {
1147///         // No need to redirect, we continue processing the request.
1148///         return Processing::Continue;
1149///     };
1150///     let location = HeaderValue::from_str(normalized_path).unwrap();
1151///     let redirect = Response::temporary_redirect().insert_header(LOCATION, location);
1152///     // Short-circuit the request processing pipeline and return a redirect response
1153///     Processing::EarlyReturn(redirect)
1154/// }
1155/// ```
1156///
1157/// # Guide
1158///
1159/// Check out the ["Middlewares"](https://pavex.dev/docs/guide/middleware/)
1160/// section of Pavex's guide for a thorough introduction to middlewares
1161/// in Pavex applications.
1162///
1163/// # Registration
1164///
1165/// Use [`Blueprint::pre_process`] to register the middleware with your [`Blueprint`].
1166///
1167/// The `#[pre_process]` macro [generates a constant](#id) that you can use to refer to the
1168/// middleware when invoking [`Blueprint::pre_process`].
1169///
1170/// # Arguments
1171///
1172/// The sections below provide an exhaustive list of all the arguments and flags supported by the [`pre_process`][macro@pre_process] macro:
1173///
1174/// | Name                | Kind     | Required |
1175/// |---------------------|----------|----------|
1176/// | [`id`](#id)         | Argument | No       |
1177///
1178/// ## `id`
1179///
1180/// By default, Pavex generates a constant named after your function
1181/// (converted to UPPER_SNAKE_CASE) that you use when registering the middleware.
1182///
1183/// The `id` argument allows you to customize the name of the generated constant.
1184///
1185/// ### Example
1186///
1187/// Using the default generated identifier:
1188///
1189/// ```rust
1190/// use pavex::{pre_process, Blueprint, middleware::Processing};
1191///
1192/// #[pre_process]
1193/// pub fn redirect_to_normalized() -> Processing {
1194///     Processing::Continue
1195/// }
1196///
1197/// # fn main() {
1198/// let mut bp = Blueprint::new();
1199/// bp.pre_process(REDIRECT_TO_NORMALIZED);
1200/// # }
1201/// ```
1202///
1203/// Using a custom identifier:
1204///
1205/// ```rust
1206/// use pavex::{pre_process, Blueprint, middleware::Processing, request::RequestHead};
1207///
1208/// #[pre_process(id = "TO_NORMALIZED")]
1209/// //            πŸ‘† Custom identifier
1210/// pub fn redirect_to_normalized(head: &RequestHead) -> Processing {
1211///     // [...]
1212///     Processing::Continue
1213/// }
1214///
1215/// # fn main() {
1216/// let mut bp = Blueprint::new();
1217/// // Use the custom identifier when registering
1218/// bp.pre_process(TO_NORMALIZED);
1219/// # }
1220/// ```
1221///
1222/// [`Blueprint::pre_process`]: crate::Blueprint::pre_process
1223/// [`Blueprint`]: crate::Blueprint
1224#[doc(alias = "middleware")]
1225pub use pavex_macros::pre_process;
1226
1227/// Define a [post-processing middleware](https://pavex.dev/docs/guide/middleware/post_processing/).
1228///
1229/// # Example
1230///
1231/// Log the status code of the HTTP response returned to the caller:
1232///
1233/// ```rust
1234/// use pavex::{post_process, Response};
1235/// use pavex_tracing::{
1236///     RootSpan,
1237///     fields::{http_response_status_code, HTTP_RESPONSE_STATUS_CODE}
1238/// };
1239///
1240/// #[post_process]
1241/// pub fn response_logger(response: Response, root_span: &RootSpan) -> Response
1242/// {
1243///     root_span.record(
1244///         HTTP_RESPONSE_STATUS_CODE,
1245///         http_response_status_code(&response),
1246///     );
1247///     response
1248/// }
1249/// ```
1250///
1251/// # Guide
1252///
1253/// Check out the ["Middlewares"](https://pavex.dev/docs/guide/middleware/)
1254/// section of Pavex's guide for a thorough introduction to middlewares
1255/// in Pavex applications.
1256///
1257/// # Registration
1258///
1259/// Use [`Blueprint::post_process`] to register the middleware with your [`Blueprint`].
1260///
1261/// The `#[post_process]` macro [generates a constant](#id) that you can use to refer to the
1262/// middleware when invoking [`Blueprint::post_process`].
1263///
1264/// # Arguments
1265///
1266/// The sections below provide an exhaustive list of all the arguments and flags supported by the [`post_process`][macro@post_process] macro:
1267///
1268/// | Name                | Kind     | Required |
1269/// |---------------------|----------|----------|
1270/// | [`id`](#id)         | Argument | No       |
1271///
1272/// ## `id`
1273///
1274/// By default, Pavex generates a constant named after your function
1275/// (converted to UPPER_SNAKE_CASE) that you use when registering the middleware.
1276///
1277/// The `id` argument allows you to customize the name of the generated constant.
1278///
1279/// ### Example
1280///
1281/// Using the default generated identifier:
1282///
1283/// ```rust
1284/// use pavex::{post_process, Blueprint, Response};
1285/// use pavex_tracing::RootSpan;
1286///
1287/// #[post_process]
1288/// pub fn response_logger(response: Response, root_span: &RootSpan) -> Response
1289/// {
1290///     // [...]
1291///     # todo!()
1292/// }
1293///
1294/// # fn main() {
1295/// let mut bp = Blueprint::new();
1296/// // The generated constant is named `RESPONSE_LOGGER`
1297/// bp.post_process(RESPONSE_LOGGER);
1298/// # }
1299/// ```
1300///
1301/// Using a custom identifier:
1302///
1303/// ```rust
1304/// use pavex::{post_process, Blueprint, Response};
1305/// use pavex_tracing::RootSpan;
1306///
1307/// #[post_process(id = "LOG_RESPONSE")]
1308/// //             πŸ‘† Custom identifier
1309/// pub fn response_logger(response: Response, root_span: &RootSpan) -> Response
1310/// {
1311///     // [...]
1312///     # todo!()
1313/// }
1314///
1315/// # fn main() {
1316/// let mut bp = Blueprint::new();
1317/// // Use the custom identifier when registering
1318/// bp.post_process(LOG_RESPONSE);
1319/// # }
1320/// ```
1321///
1322/// [`Blueprint::post_process`]: crate::Blueprint::post_process
1323/// [`Blueprint`]: crate::Blueprint
1324#[doc(alias = "middleware")]
1325pub use pavex_macros::post_process;
1326
1327/// Define an [error handler](https://pavex.dev/docs/guide/errors/error_handlers/).
1328///
1329/// Error handlers are invoked whenever an error occurs during request processing,
1330/// allowing you to transform errors into HTTP responses.
1331///
1332/// # Example
1333///
1334/// ```rust
1335/// use pavex::error_handler;
1336/// use pavex::Response;
1337/// # struct AuthError;
1338///
1339/// #[error_handler]
1340/// pub fn handle_auth_error(e: &AuthError) -> Response {
1341///     // Transform the error into an HTTP response
1342///     Response::unauthorized()
1343/// }
1344/// ```
1345///
1346/// # Guide
1347///
1348/// Check out the [\"Error handling\"](https://pavex.dev/docs/guide/errors)
1349/// section of Pavex's guide for a thorough introduction to error handling
1350/// in Pavex applications.
1351///
1352/// # Registration
1353///
1354/// You can register an error handler with your application in two ways:
1355/// - Use [`Blueprint::error_handler`] to register a single error handler
1356/// - Use [`Blueprint::import`] to import multiple error handlers in bulk
1357///
1358/// The `#[error_handler]` macro [generates a constant](#id) that you can use to refer to the
1359/// error handler when invoking [`Blueprint::error_handler`].
1360///
1361/// # Arguments
1362///
1363/// The sections below provide an exhaustive list of all the arguments and helper attributes supported by the [`error_handler`][macro@error_handler] macro:
1364///
1365/// | Name                          | Kind             | Required  |
1366/// |-------------------------------|------------------|-----------|
1367/// | [`px(error_ref)`](#error_ref) | Helper attribute | Sometimes |
1368/// | [`id`](#id)                   | Argument         | No        |
1369/// | [`default`](#default)         | Argument         | No        |
1370///
1371/// ## `error_ref`
1372///
1373/// One of the input parameters for an error handler must be a reference to the error type that's being handled.
1374///
1375/// Pavex infers the error type automatically if the error handler has a single input parameter.\
1376/// If there are multiple input parameters, you must annotate the error reference with `#[px(error_ref)]`.
1377///
1378/// ### Example: single input parameter
1379///
1380/// ```rust
1381/// use pavex::methods;
1382/// use pavex::Response;
1383///
1384/// pub struct AuthError { /* */ };
1385///
1386/// #[methods]
1387/// impl AuthError {
1388///     #[error_handler]
1389///     // A single input parameter, no need for additional annotations
1390///     // Pavex will infer that `&self` is the error reference
1391///     pub fn to_response(&self) -> Response {
1392///         // [...]
1393///         # Response::ok()
1394///     }
1395/// }
1396/// ```
1397///
1398/// ### Example: multiple input parameters
1399///
1400/// ```rust
1401/// use pavex::methods;
1402/// use pavex::Response;
1403///
1404/// pub struct AuthError { /* */ };
1405/// # pub struct OrgId;
1406///
1407/// #[methods]
1408/// impl AuthError {
1409///     #[error_handler]
1410///     pub fn to_response(
1411///         #[px(error_ref)] &self,
1412///         // πŸ‘†
1413///         // Multiple input parameters, you must mark the error reference
1414///         organization_id: OrgId
1415///     ) -> Response {
1416///         // [...]
1417///         # Response::ok()
1418///     }
1419/// }
1420/// ```
1421///
1422/// ## `id`
1423///
1424/// When using [`Blueprint::error_handler`], Pavex generates a constant named after your function
1425/// (converted to UPPER_SNAKE_CASE) that you can use to refer to the error handler
1426/// when invoking [`Blueprint::error_handler`].
1427///
1428/// The `id` argument allows you to customize the name of the generated constant.
1429///
1430/// ### Example
1431///
1432/// Using the default identifier:
1433///
1434/// ```rust
1435/// use pavex::{error_handler, Blueprint};
1436/// use pavex::Response;
1437/// # struct AuthError;
1438///
1439/// #[error_handler]
1440/// pub fn handle_auth_error(e: &AuthError) -> Response {
1441///     // [...]
1442///     # todo!()
1443/// }
1444///
1445/// let mut bp = Blueprint::new();
1446/// bp.error_handler(HANDLE_AUTH_ERROR);
1447/// ```
1448///
1449/// Using a custom identifier:
1450///
1451/// ```rust
1452/// use pavex::{error_handler, Blueprint};
1453/// use pavex::Response;
1454///
1455/// #[error_handler(id = "AUTH_HANDLER")]
1456/// //              πŸ‘† Custom identifier
1457/// pub fn handle_auth_error(e: &AuthError) -> Response {
1458///     // [...]
1459///     # todo!()
1460/// }
1461///
1462/// let mut bp = Blueprint::new();
1463/// bp.error_handler(AUTH_HANDLER);
1464/// # struct AuthError;
1465/// ```
1466///
1467/// ## `default`
1468///
1469/// The `default` argument determines whether this error handler should be used as the
1470/// default handler for the error type whenever an error of the matching type is emitted.
1471///
1472/// By default, error handlers are considered the default handler for their error type (`default = true`).
1473///
1474/// ### Example
1475///
1476/// ```rust
1477/// use pavex::{error_handler, get, Blueprint};
1478/// use pavex::Response;
1479///
1480/// #[error_handler]
1481/// // This is the default handler for `AuthError`s
1482/// pub fn handle_auth_error(e: &AuthError) -> Response {
1483///     # todo!()
1484/// }
1485///
1486/// #[error_handler(default = false)]
1487/// //              πŸ‘† Not the default handler
1488/// pub fn handle_auth_error_admin(e: &AuthError) -> Response {
1489///     # todo!()
1490/// }
1491///
1492/// #[get(path = "/admin")]
1493/// pub fn admin_route() -> Result<Response, AuthError> {
1494///     // Admin-specific logic
1495///     # todo!()
1496/// }
1497///
1498/// let mut bp = Blueprint::new();
1499/// // Register the default error handler
1500/// bp.error_handler(HANDLE_AUTH_ERROR);
1501/// // Specify a different error handler for the admin route
1502/// bp.route(ADMIN_ROUTE).error_handler(HANDLE_AUTH_ERROR_ADMIN);
1503/// # struct AuthError;
1504/// ```
1505pub use pavex_macros::error_handler;
1506
1507/// Define an [error observer](https://pavex.dev/docs/guide/errors/error_observers/).
1508///
1509/// Error observers are invoked whenever an error occurs during request processing,
1510/// allowing you to log errors, send them to monitoring services, or perform other
1511/// observability tasks.
1512///
1513/// # Example
1514///
1515/// Log errors that occur during request processing:
1516///
1517/// ```rust
1518/// use pavex::error_observer;
1519/// use tracing_log_error::log_error;
1520///
1521/// #[error_observer]
1522/// pub async fn error_logger(e: &pavex::Error) {
1523///     log_error!(e)
1524/// }
1525/// ```
1526///
1527/// # Guide
1528///
1529/// Check out the ["Errors"](https://pavex.dev/docs/guide/errors/)
1530/// section of Pavex's guide for a thorough introduction to errors
1531/// in Pavex applications.
1532///
1533/// # Registration
1534///
1535/// Use [`Blueprint::error_observer`] to register the error observer with your [`Blueprint`].
1536///
1537/// The `#[error_observer]` macro [generates a constant](#id) that you can use to refer to the
1538/// observer when invoking [`Blueprint::error_observer`].
1539///
1540/// # Arguments
1541///
1542/// The sections below provide an exhaustive list of all the arguments and flags supported by the [`error_observer`][macro@error_observer] macro:
1543///
1544/// | Name                | Kind     | Required |
1545/// |---------------------|----------|----------|
1546/// | [`id`](#id)         | Argument | No       |
1547///
1548/// ## `id`
1549///
1550/// By default, Pavex generates a constant named after your function
1551/// (converted to UPPER_SNAKE_CASE) that you use when registering the error observer.
1552///
1553/// The `id` argument allows you to customize the name of the generated constant.
1554///
1555/// ### Example
1556///
1557/// Using the default generated identifier:
1558///
1559/// ```rust
1560/// use pavex::{error_observer, Blueprint};
1561///
1562/// #[error_observer]
1563/// pub async fn error_logger(e: &pavex::Error) {
1564///     // Log the error
1565/// }
1566///
1567/// # fn main() {
1568/// let mut bp = Blueprint::new();
1569/// // The generated constant is named `ERROR_LOGGER`
1570/// bp.error_observer(ERROR_LOGGER);
1571/// # }
1572/// ```
1573///
1574/// Using a custom identifier:
1575///
1576/// ```rust
1577/// use pavex::{error_observer, Blueprint};
1578///
1579/// #[error_observer(id = "MY_ERROR_LOGGER")]
1580/// //               πŸ‘† Custom identifier
1581/// pub async fn error_logger(e: &pavex::Error) {
1582///     // Log the error
1583/// }
1584///
1585/// # fn main() {
1586/// let mut bp = Blueprint::new();
1587/// // Use the custom identifier when registering
1588/// bp.error_observer(MY_ERROR_LOGGER);
1589/// # }
1590/// ```
1591///
1592/// [`Blueprint::error_observer`]: crate::Blueprint::error_observer
1593/// [`Blueprint`]: crate::Blueprint
1594pub use pavex_macros::error_observer;
1595
1596macro_rules! http_method_macro_doc {
1597    ($method:literal, $macro_name:ident, $example_fn:ident, $constant_name:ident, $example_path:literal, $example_comment:literal) => {
1598        #[doc = concat!("Define a [route](https://pavex.dev/docs/guide/routing/) for ", $method, " requests to a given path.")]
1599        ///
1600        #[doc = concat!("This is a shorthand for [`#[route(method = \"", $method, "\", path = \"...\")]`](macro@route).")]
1601        ///
1602        /// # Example
1603        ///
1604        /// ```rust
1605        #[doc = concat!("use pavex::{", stringify!($macro_name), ", Response};")]
1606        ///
1607        #[doc = concat!("#[", stringify!($macro_name), "(path = \"", $example_path, "\")]")]
1608        #[doc = concat!("pub async fn ", stringify!($example_fn), "(/* */) -> Response {")]
1609        #[doc = concat!("    // ", $example_comment)]
1610        ///     // [...]
1611        ///     # Response::ok()
1612        /// }
1613        /// ```
1614        ///
1615        /// # Guide
1616        ///
1617        /// Check out the ["Routing"](https://pavex.dev/docs/guide/routing/)
1618        /// section of Pavex's guide for a thorough introduction to routing
1619        /// in Pavex applications.
1620        ///
1621        /// # Registration
1622        ///
1623        #[doc = concat!("You can register a ", $method, " route with your application in two ways:")]
1624        /// - Use [`Blueprint::route`] to register a single route
1625        /// - Use [`Blueprint::import`] to import multiple routes in bulk
1626        ///
1627        #[doc = concat!("The `#[", stringify!($macro_name), "]` macro [generates a constant](#id) that you can use to refer to the")]
1628        /// route when invoking [`Blueprint::route`].
1629        ///
1630        /// # Arguments
1631        ///
1632        #[doc = concat!("The sections below provide an exhaustive list of all the arguments supported by the [`", stringify!($macro_name), "`][macro@", stringify!($macro_name), "] macro:")]
1633        ///
1634        /// | Name                              | Kind     | Required |
1635        /// |-----------------------------------|----------|----------|
1636        /// | [`path`](#path)                   | Argument | Yes      |
1637        /// | [`id`](#id)                       | Argument | No       |
1638        ///
1639        /// ## `path`
1640        ///
1641        /// The `path` argument specifies the URL path pattern that this route will match.
1642        ///
1643        /// The path can contain dynamic parameter placeholders in the format `{parameter_name}`.
1644        /// Check out the [guide on parameter extraction](https://pavex.dev/docs/guide/routing/path_patterns/#path-parameters)
1645        /// for a detailed explanation.
1646        ///
1647        /// ### Example
1648        ///
1649        /// ```rust
1650        #[doc = concat!("use pavex::{", stringify!($macro_name), ", Response};")]
1651        ///
1652        #[doc = concat!("#[", stringify!($macro_name), "(path = \"", $example_path, "\")]")]
1653        /// //           πŸ‘† Path with parameter
1654        #[doc = concat!("pub async fn ", stringify!($example_fn), "(/* */) -> Response {")]
1655        ///     // [...]
1656        ///     # Response::ok()
1657        /// }
1658        /// ```
1659        ///
1660        /// ## `id`
1661        ///
1662        /// By default, Pavex generates a constant named after your function
1663        /// (converted to UPPER_SNAKE_CASE) that you can use when invoking [`Blueprint::route`].
1664        ///
1665        /// The `id` argument allows you to customize the name of the generated constant.
1666        ///
1667        /// ### Example
1668        ///
1669        /// Using the default generated identifier:
1670        ///
1671        /// ```rust
1672        #[doc = concat!("use pavex::{", stringify!($macro_name), ", Response, Blueprint};")]
1673        ///
1674        #[doc = concat!("#[", stringify!($macro_name), "(path = \"", $example_path, "\")]")]
1675        #[doc = concat!("pub async fn ", stringify!($example_fn), "(/* */) -> Response {")]
1676        ///     // [...]
1677        ///     # Response::ok()
1678        /// }
1679        ///
1680        /// # fn main() {
1681        /// let mut bp = Blueprint::new();
1682        #[doc = concat!("// The generated constant is named `", stringify!($constant_name), "`")]
1683        #[doc = concat!("bp.route(", stringify!($constant_name), ");")]
1684        /// # }
1685        /// ```
1686        ///
1687        /// Using a custom identifier:
1688        ///
1689        /// ```rust
1690        #[doc = concat!("use pavex::{", stringify!($macro_name), ", Response, Blueprint};")]
1691        ///
1692        #[doc = concat!("#[", stringify!($macro_name), "(path = \"", $example_path, "\", id = \"CUSTOM_ROUTE\")]")]
1693        /// //                           πŸ‘† Custom identifier
1694        #[doc = concat!("pub async fn ", stringify!($example_fn), "(id: u32) -> Response {")]
1695        ///     // [...]
1696        ///     # Response::ok()
1697        /// }
1698        ///
1699        /// # fn main() {
1700        /// let mut bp = Blueprint::new();
1701        /// // Use the custom identifier when registering
1702        /// bp.route(CUSTOM_ROUTE);
1703        /// # }
1704        /// ```
1705        ///
1706        /// [`Blueprint::import`]: crate::Blueprint::import
1707        /// [`Blueprint::route`]: crate::Blueprint::route
1708        #[doc(alias = "route")]
1709        #[doc(alias = "request_handler")]
1710        pub use pavex_macros::$macro_name;
1711    };
1712}
1713
1714http_method_macro_doc!(
1715    "DELETE",
1716    delete,
1717    delete_user,
1718    DELETE_USER,
1719    "/users/{id}",
1720    "Delete user logic"
1721);
1722http_method_macro_doc!(
1723    "GET",
1724    get,
1725    get_user,
1726    GET_USER,
1727    "/users/{id}",
1728    "Get user logic"
1729);
1730http_method_macro_doc!(
1731    "HEAD",
1732    head,
1733    head_user,
1734    HEAD_USER,
1735    "/users/{id}",
1736    "Head user logic"
1737);
1738http_method_macro_doc!(
1739    "OPTIONS",
1740    options,
1741    options_user,
1742    OPTIONS_USER,
1743    "/users/{id}",
1744    "Options user logic"
1745);
1746http_method_macro_doc!(
1747    "PATCH",
1748    patch,
1749    patch_user,
1750    PATCH_USER,
1751    "/users/{id}",
1752    "Patch user logic"
1753);
1754http_method_macro_doc!(
1755    "POST",
1756    post,
1757    create_user,
1758    CREATE_USER,
1759    "/users",
1760    "Create user logic"
1761);
1762http_method_macro_doc!(
1763    "PUT",
1764    put,
1765    put_user,
1766    PUT_USER,
1767    "/users/{id}",
1768    "Put user logic"
1769);
1770
1771/// Define a [fallback handler](https://pavex.dev/docs/guide/routing/).
1772///
1773/// A fallback handler is invoked when no other route matches the incoming request.
1774/// It's typically used to return a 404 Not Found response or redirect to a default page.
1775///
1776/// # Example
1777///
1778/// ```rust
1779/// use pavex::{fallback, Response};
1780///
1781/// #[fallback]
1782/// pub async fn not_found() -> Response {
1783///     Response::not_found()
1784///         .set_typed_body("The page you are looking for does not exist")
1785/// }
1786/// ```
1787///
1788/// # Guide
1789///
1790/// Check out the ["Routing"](https://pavex.dev/docs/guide/routing/)
1791/// section of Pavex's guide for a thorough introduction to routing
1792/// in Pavex applications.
1793///
1794/// # Registration
1795///
1796/// Use [`Blueprint::fallback`] to register the fallback handler with your [`Blueprint`].
1797///
1798/// The `#[fallback]` macro [generates a constant](#id) that you can use to refer to the
1799/// fallback handler when invoking [`Blueprint::fallback`].
1800///
1801/// # Arguments
1802///
1803/// The sections below provide an exhaustive list of all the arguments and flags supported by the [`fallback`][macro@fallback] macro:
1804///
1805/// | Name                | Kind     | Required |
1806/// |---------------------|----------|----------|
1807/// | [`id`](#id)         | Argument | No       |
1808///
1809/// ## `id`
1810///
1811/// By default, Pavex generates a constant named after your function
1812/// (converted to UPPER_SNAKE_CASE) that you use when registering the fallback handler.
1813///
1814/// The `id` argument allows you to customize the name of the generated constant.
1815///
1816/// ### Example
1817///
1818/// Using the default generated identifier:
1819///
1820/// ```rust
1821/// use pavex::{fallback, Blueprint, Response};
1822///
1823/// #[fallback]
1824/// pub async fn not_found() -> Response {
1825///     Response::not_found()
1826/// }
1827///
1828/// # fn main() {
1829/// let mut bp = Blueprint::new();
1830/// // The generated constant is named `NOT_FOUND`
1831/// bp.fallback(NOT_FOUND);
1832/// # }
1833/// ```
1834///
1835/// Using a custom identifier:
1836///
1837/// ```rust
1838/// use pavex::{fallback, Blueprint, Response};
1839///
1840/// #[fallback(id = "CUSTOM_404")]
1841/// //         πŸ‘† Custom identifier
1842/// pub async fn not_found() -> Response {
1843///     Response::not_found()
1844/// }
1845///
1846/// # fn main() {
1847/// let mut bp = Blueprint::new();
1848/// // Use the custom identifier when registering
1849/// bp.fallback(CUSTOM_404);
1850/// # }
1851/// ```
1852///
1853/// [`Blueprint::fallback`]: crate::Blueprint::fallback
1854/// [`Blueprint`]: crate::Blueprint
1855pub use pavex_macros::fallback;
1856
1857/// Define a [route](https://pavex.dev/docs/guide/routing/) for requests to a given path.
1858///
1859/// The `#[route]` macro can be used to define routes that match multiple HTTP methods, or
1860/// non-standard ones (e.g. `QUERY`).
1861/// Prefer one of the short-hand attributes if you need to match a standard HTTP method:
1862/// [`#[get]`](crate::get), [`#[post]`](crate::post), [`#[put]`](crate::put), [`#[patch]`](crate::patch),
1863/// [`#[delete]`](crate::delete), [`#[head]`](crate::head), and [`#[options]`](crate::options).
1864///
1865/// # Example: Multiple methods
1866///
1867/// ```rust
1868/// use pavex::{route, Response};
1869///
1870/// #[route(method = ["GET", "HEAD"], path = "/users/{id}")]
1871/// //      πŸ‘† Multiple methods
1872/// pub async fn get_or_head_user(/* */) -> Response {
1873///     // [...]
1874///     # Response::ok()
1875/// }
1876/// ```
1877///
1878/// # Guide
1879///
1880/// Check out the ["Routing"](https://pavex.dev/docs/guide/routing/)
1881/// section of Pavex's guide for a thorough introduction to routing
1882/// in Pavex applications.
1883///
1884/// # Registration
1885///
1886/// You can register a route with your application in two ways:
1887/// - Use [`Blueprint::route`] to register a single route
1888/// - Use [`Blueprint::routes`] to register multiple routes in bulk
1889///
1890/// The `#[route]` macro [generates a constant](#id) that you can use to refer to the
1891/// route when invoking [`Blueprint::route`].
1892///
1893/// # Arguments
1894///
1895/// The sections below provide an exhaustive list of all the arguments supported by the [`route`][macro@route] macro:
1896///
1897/// | Name                      | Kind     | Required |
1898/// |---------------------------|----------|----------|
1899/// | [`method`](#method)       | Argument | Yes*     |
1900/// | [`path`](#path)           | Argument | Yes      |
1901/// | [`id`](#id)               | Argument | No       |
1902/// | [`allow`](#allow)         | Argument | No       |
1903///
1904/// \* The `method` argument is required unless [`allow(any_method)`](#allow) is specified.
1905///
1906/// ## `method`
1907///
1908/// The `method` argument specifies the HTTP method(s) that this route will match.
1909/// You can specify a single method or multiple methods.
1910///
1911/// `method` is required unless you specified [`allow(any_method)`](#allow) to accept
1912/// any HTTP method.
1913///
1914/// ### Example
1915///
1916/// Single method:
1917///
1918/// ```rust
1919/// use pavex::{route, Response};
1920///
1921/// #[route(method = "POST", path = "/users/{id}")]
1922/// //       πŸ‘† Single method
1923/// pub async fn create_user(/* */) -> Response {
1924///     // [...]
1925///     # Response::ok()
1926/// }
1927/// ```
1928///
1929/// Multiple methods:
1930///
1931/// ```rust
1932/// use pavex::{route, Response};
1933///
1934/// #[route(method = ["GET", "HEAD"], path = "/users/{id}")]
1935/// //       πŸ‘† Multiple methods
1936/// pub async fn get_or_head_user(/* */) -> Response {
1937///     // [...]
1938///     # Response::ok()
1939/// }
1940/// ```
1941///
1942/// ## `path`
1943///
1944/// The `path` argument specifies the URL path pattern that this route will match.
1945///
1946/// The path can contain parameter placeholders in the format `{parameter_name}` that will
1947/// be extracted and passed to your handler function.
1948///
1949/// ### Example
1950///
1951/// ```rust
1952/// use pavex::{route, Response};
1953///
1954/// #[route(method = "GET", path = "/users/{id}/posts/{post_id}")]
1955/// //                            πŸ‘† Path with multiple parameters
1956/// pub async fn get_user_post(/* */) -> Response {
1957///     // [...]
1958///     # Response::ok()
1959/// }
1960/// ```
1961///
1962/// ## `id`
1963///
1964/// By default, Pavex generates a constant named after your function
1965/// (converted to UPPER_SNAKE_CASE) that you use when registering the route.
1966///
1967/// The `id` argument allows you to customize the name of the generated constant.
1968///
1969/// ### Example
1970///
1971/// Using the default generated identifier:
1972///
1973/// ```rust
1974/// use pavex::{route, Response, Blueprint};
1975///
1976/// #[route(method = "GET", path = "/users/{id}")]
1977/// pub async fn get_user(/* */) -> Response {
1978///     // [...]
1979///     # Response::ok()
1980/// }
1981///
1982/// # fn main() {
1983/// let mut bp = Blueprint::new();
1984/// // The generated constant is named `GET_USER`
1985/// bp.route(GET_USER);
1986/// # }
1987/// ```
1988///
1989/// Using a custom identifier:
1990///
1991/// ```rust
1992/// use pavex::{route, Response, Blueprint};
1993///
1994/// #[route(method = "GET", path = "/users/{id}", id = "USER_ROUTE")]
1995/// //                                            πŸ‘† Custom identifier
1996/// pub async fn get_user(/* */) -> Response {
1997///     // [...]
1998///     # Response::ok()
1999/// }
2000///
2001/// # fn main() {
2002/// let mut bp = Blueprint::new();
2003/// // Use the custom identifier when registering
2004/// bp.route(USER_ROUTE);
2005/// # }
2006/// ```
2007///
2008/// ## `allow`
2009///
2010/// The `allow` argument can be used to enable additional behaviors for this route.
2011///
2012/// Currently, the following values are supported:
2013/// - `non_standard_methods`: Allow non-standard HTTP methods
2014/// - `any_method`: Match any HTTP method.
2015///   It matches non-standard methods if `non_standard_methods` is also enabled.
2016///
2017/// ### Example: Non-standard method
2018///
2019/// Allow non-standard methods:
2020///
2021/// ```rust
2022/// use pavex::{route, Response};
2023///
2024/// #[route(method = "QUERY", path = "/users", allow(non_standard_methods))]
2025/// //                                         πŸ‘† Allow non-standard methods
2026/// pub async fn query_users() -> Response {
2027///     // [...]
2028///     # Response::ok()
2029/// }
2030/// ```
2031///
2032/// ### Example: Any standard method
2033///
2034/// Allow any method (no need to specify `method`):
2035///
2036/// ```rust
2037/// use pavex::{route, Response};
2038///
2039/// #[route(path = "/webhook", allow(any_method))]
2040/// //                         πŸ‘† Allow any HTTP method
2041/// pub async fn webhook() -> Response {
2042///     // [...]
2043///     # Response::ok()
2044/// }
2045/// ```
2046///
2047/// ### Example: Arbitrary methods
2048///
2049/// Allow any method, including non-standard ones:
2050///
2051/// ```rust
2052/// use pavex::{route, Response};
2053///
2054/// #[route(path = "/webhook", allow(any_method, non_standard_methods))]
2055/// //                         πŸ‘† Allow any HTTP method, including non-standard ones
2056/// pub async fn webhook() -> Response {
2057///     // [...]
2058///     # Response::ok()
2059/// }
2060/// ```
2061///
2062/// [`Blueprint::route`]: crate::Blueprint::route
2063/// [`Blueprint::routes`]: crate::Blueprint::routes
2064pub use pavex_macros::route;
2065
2066/// A helper macro to support Pavex attributes on methods.
2067///
2068/// You must annotate the `impl` block with `#[methods]` whenever you want to add Pavex attributes
2069/// like `#[get]`, `#[request_scoped]`, or `#[error_handler]` to methods defined in that `impl` block.
2070///
2071/// Without `#[methods]`, Pavex will reject the annotated methods.
2072///
2073/// # Example
2074///
2075/// ```rust
2076/// use pavex::methods;
2077/// use pavex::Response;
2078///
2079/// pub struct UserService {
2080///     // [...]
2081/// };
2082///
2083/// #[methods]  // Required for the macros below to work
2084/// impl UserService {
2085///     #[request_scoped]
2086///     pub fn new() -> Self {
2087///         // [...]
2088///         # Self {}
2089///     }
2090///
2091///     #[get(path = "/users/{id}")]
2092///     pub fn get_user(/* */) -> Result<Response, GetUserError> {
2093///         // [...]
2094///         # Ok(Response::ok())
2095///     }
2096///
2097///     #[post(path = "/users/{id}")]
2098///     pub fn create_user(/* */) -> Result<Response, CreateUserError> {
2099///         // [...]
2100///         # Ok(Response::ok())
2101///     }
2102/// }
2103/// # struct CreateUserError;
2104/// # struct GetUserError;
2105/// ```
2106///
2107/// # Supported Annotations
2108///
2109/// All Pavex attributes can be attached to both methods and functions.
2110pub use pavex_macros::methods;