Skip to main content

vox_types/
request_context.rs

1use std::sync::OnceLock;
2
3use crate::{Extensions, MetadataEntry, MethodDescriptor};
4
5/// Borrowed per-request context exposed to opted-in Rust service handlers.
6///
7/// This is constructed by generated dispatchers from the inbound request and
8/// borrows request metadata directly rather than cloning it.
9#[derive(Clone, Copy, Debug)]
10pub struct RequestContext<'a> {
11    method: &'static MethodDescriptor,
12    metadata: &'a [MetadataEntry<'static>],
13    extensions: &'a Extensions,
14}
15
16impl<'a> RequestContext<'a> {
17    /// Create a new borrowed request context.
18    pub fn new(method: &'static MethodDescriptor, metadata: &'a [MetadataEntry<'static>]) -> Self {
19        Self::with_extensions(method, metadata, empty_extensions())
20    }
21
22    /// Create a new borrowed request context with middleware extensions.
23    pub fn with_extensions(
24        method: &'static MethodDescriptor,
25        metadata: &'a [MetadataEntry<'static>],
26        extensions: &'a Extensions,
27    ) -> Self {
28        Self {
29            method,
30            metadata,
31            extensions,
32        }
33    }
34
35    /// Static descriptor for the method being handled.
36    pub fn method(&self) -> &'static MethodDescriptor {
37        self.method
38    }
39
40    /// Request metadata borrowed from the inbound call.
41    pub fn metadata(&self) -> &'a [MetadataEntry<'static>] {
42        self.metadata
43    }
44
45    /// Per-request middleware extensions bag.
46    pub fn extensions(&self) -> &'a Extensions {
47        self.extensions
48    }
49}
50
51fn empty_extensions() -> &'static Extensions {
52    static EMPTY: OnceLock<Extensions> = OnceLock::new();
53    EMPTY.get_or_init(Extensions::new)
54}