Skip to main content

ferro_inertia/
request.rs

1//! Request trait for framework-agnostic Inertia header extraction.
2
3/// Trait for extracting Inertia-specific data from HTTP requests.
4///
5/// Implement this trait for your framework's request type to enable
6/// Inertia.js integration.
7///
8/// # Example
9///
10/// ```rust,ignore
11/// use ferro_inertia::InertiaRequest;
12///
13/// impl InertiaRequest for axum::extract::Request {
14///     fn inertia_header(&self, name: &str) -> Option<&str> {
15///         self.headers()
16///             .get(name)
17///             .and_then(|v| v.to_str().ok())
18///     }
19///
20///     fn path(&self) -> &str {
21///         self.uri().path()
22///     }
23/// }
24/// ```
25pub trait InertiaRequest {
26    /// Get a header value by name.
27    ///
28    /// Used to extract Inertia-specific headers like `X-Inertia`,
29    /// `X-Inertia-Version`, and `X-Inertia-Partial-Data`.
30    fn inertia_header(&self, name: &str) -> Option<&str>;
31
32    /// Get the request path (URL path component).
33    fn path(&self) -> &str;
34
35    /// Check if this is an Inertia XHR request.
36    ///
37    /// Returns `true` if the `X-Inertia` header is present and set to "true".
38    fn is_inertia(&self) -> bool {
39        self.inertia_header("X-Inertia")
40            .map(|v| v == "true")
41            .unwrap_or(false)
42    }
43
44    /// Get the Inertia asset version from the request.
45    ///
46    /// Returns the value of the `X-Inertia-Version` header if present.
47    fn inertia_version(&self) -> Option<&str> {
48        self.inertia_header("X-Inertia-Version")
49    }
50
51    /// Get the partial reload data keys.
52    ///
53    /// Returns a list of prop keys requested for partial reload via
54    /// the `X-Inertia-Partial-Data` header.
55    fn inertia_partial_data(&self) -> Option<Vec<&str>> {
56        self.inertia_header("X-Inertia-Partial-Data")
57            .map(|v| v.split(',').map(str::trim).collect())
58    }
59
60    /// Get the component name for partial reload.
61    ///
62    /// Returns the value of the `X-Inertia-Partial-Component` header.
63    fn inertia_partial_component(&self) -> Option<&str> {
64        self.inertia_header("X-Inertia-Partial-Component")
65    }
66
67    /// Check if the request accepts JSON responses.
68    ///
69    /// Returns `true` if the `Accept` header contains `application/json`.
70    fn accepts_json(&self) -> bool {
71        self.inertia_header("Accept")
72            .map(|v| v.contains("application/json"))
73            .unwrap_or(false)
74    }
75}