Skip to main content

ferro_inertia/
shared.rs

1//! Shared props that are merged into every Inertia response.
2
3use serde::Serialize;
4
5/// Shared props that are merged into every Inertia response.
6///
7/// Use this struct to pass common data (auth, flash messages, CSRF tokens)
8/// to all Inertia responses via middleware.
9///
10/// # Example
11///
12/// ```rust
13/// use ferro_inertia::InertiaShared;
14/// use serde_json::json;
15///
16/// let shared = InertiaShared::new()
17///     .auth(json!({
18///         "id": 1,
19///         "name": "John Doe",
20///         "email": "john@example.com"
21///     }))
22///     .csrf("token123")
23///     .flash(json!({
24///         "success": "Profile updated!"
25///     }));
26/// ```
27#[derive(Clone, Default, Debug, Serialize)]
28pub struct InertiaShared {
29    /// Authenticated user data (if any)
30    #[serde(skip_serializing_if = "Option::is_none")]
31    pub auth: Option<serde_json::Value>,
32    /// Flash messages from the session
33    #[serde(skip_serializing_if = "Option::is_none")]
34    pub flash: Option<serde_json::Value>,
35    /// CSRF token
36    #[serde(skip_serializing_if = "Option::is_none")]
37    pub csrf: Option<String>,
38    /// Additional custom shared props
39    #[serde(flatten, skip_serializing_if = "Option::is_none")]
40    pub extra: Option<serde_json::Value>,
41}
42
43impl InertiaShared {
44    /// Create a new empty shared props container.
45    pub fn new() -> Self {
46        Self::default()
47    }
48
49    /// Set authenticated user data.
50    pub fn auth(mut self, auth: impl Serialize) -> Self {
51        self.auth = Some(serde_json::to_value(auth).unwrap_or_default());
52        self
53    }
54
55    /// Set flash messages.
56    pub fn flash(mut self, flash: impl Serialize) -> Self {
57        self.flash = Some(serde_json::to_value(flash).unwrap_or_default());
58        self
59    }
60
61    /// Set CSRF token.
62    pub fn csrf(mut self, token: impl Into<String>) -> Self {
63        self.csrf = Some(token.into());
64        self
65    }
66
67    /// Set additional custom shared props.
68    ///
69    /// These will be flattened into the shared props object.
70    pub fn with(mut self, extra: impl Serialize) -> Self {
71        self.extra = Some(serde_json::to_value(extra).unwrap_or_default());
72        self
73    }
74
75    /// Merge shared props into a props object.
76    pub fn merge_into(&self, props: &mut serde_json::Value) {
77        if let serde_json::Value::Object(ref mut map) = props {
78            if let Some(auth) = &self.auth {
79                map.insert("auth".to_string(), auth.clone());
80            }
81            if let Some(flash) = &self.flash {
82                map.insert("flash".to_string(), flash.clone());
83            }
84            if let Some(csrf) = &self.csrf {
85                map.insert("csrf".to_string(), serde_json::Value::String(csrf.clone()));
86            }
87            if let Some(serde_json::Value::Object(extra_map)) = &self.extra {
88                for (k, v) in extra_map {
89                    map.insert(k.clone(), v.clone());
90                }
91            }
92        }
93    }
94}