1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
//! High-level response types for the Arcature application DX layer (A4).
//!
//! These types let a controller return `Result<Json<T>>`, `Result<Empty>`,
//! or `Result<Page<T>>` without manually implementing Axum response plumbing.
//! Each type implements [`axum::response::IntoResponse`] using the
//! established `(status, headers, body).into_response()` pattern.
//!
//! ## Serialize does NOT imply browser-safe
//!
//! `Json<T>` and `Page<T>` require `T: Serialize` for the wire format, but
//! serialization is not a security boundary. A `SeaORM` model that
//! `Serialize`s must not automatically become `ClientData`. Page/Resource
//! declarations are explicit exposure boundaries (PROGRAM.md "Client exposure
//! firewall"). These response types are the server-side rendering seam;
//! browser exposure is governed by the Inertia `PageContract` / `ClientData`
//! system, not by `Serialize` alone.
use ;
use HeaderValue;
use ;
/// A JSON response body. Serializes `T` to JSON and sets
/// `Content-Type: application/json`.
///
/// This is Arcature's `Json<T>` — a replacement for `axum::Json` so normal
/// application code never names `axum::` directly. It implements
/// [`IntoResponse`] directly, so a controller can return
/// `Result<Json<UserResource>>` with no manual response plumbing.
///
/// # Example
///
/// ```ignore
/// use arcature::Json;
///
/// async fn show() -> Result<Json<UserResource>> {
/// Ok(Json(UserResource { id: 42, name: "Alice".into() }))
/// }
/// ```
///
/// `Serialize` does NOT imply browser-safe. The exposure boundary for
/// Inertia `ClientData` is the `PageContract` system, not `Serialize`.
;
/// An empty response (204 No Content).
///
/// Use when a handler has nothing to return — e.g. a `DELETE` that succeeded.
///
/// # Example
///
/// ```ignore
/// use arcature::Empty;
///
/// async fn destroy() -> Result<Empty> {
/// // ... delete the resource ...
/// Ok(Empty)
/// }
/// ```
;
/// A generic page response shell (A4).
///
/// `Page<T>` is the high-level response type for Inertia-rendered pages.
/// In A4, it is a thin shell that serializes `T` as JSON. The full
/// `#[page]` / `page!` declaration machinery, `PageContract` integration,
/// `ClientData` exposure, and Cross-Stack Linker wiring arrive in A6.
///
/// `Page<T>` is also the **golden-path return type** for the `#[controller]`
/// macro's page-response derivation (AP2.1-4): a handler returning
/// `Result<Page<T>, E>` or `Page<T>` has its page identity
/// (`T::PAGE_CONTRACT.name()`) inferred into the controller metadata, so the
/// route needs no `page:` / `pages:` declaration. The `T` must be a `#[page]`
/// type — `T::PAGE_CONTRACT` exists only then, so a non-page type fails to
/// compile (the Client Exposure Firewall applied to the return type).
///
/// # Example
///
/// ```ignore
/// use arcature::{Page, page};
///
/// async fn show() -> Result<Page<ShowLinkPage>> {
/// Ok(page(ShowLinkPage { link: LinkResource::from(link) }))
/// }
/// ```
///
/// `Serialize` does NOT imply browser-safe. The `T` in `Page<T>` must be a
/// declared page/resource with explicit exposure boundaries (PROGRAM.md
/// "Client exposure firewall").
;
/// Construct a [`Page<T>`] from its props — the ergonomic golden-path
/// constructor for handlers returning `Result<Page<T>, E>` / `Page<T>`.
///
/// The `#[controller]` macro derives the route→page edge from the return
/// type's `Page<T>` (reading the signature, not the body), so a handler
/// returning `Page<HomePage>` needs no `page:` route declaration — the page
/// identity is inferred from `HomePage::PAGE_CONTRACT.name()` at compile
/// time.
///
/// # Example
///
/// ```ignore
/// use arcature::{Page, page};
///
/// async fn home() -> Result<Page<HomePage>, AppError> {
/// Ok(page(HomePage { name: "Arcature".to_string() }))
/// }
/// ```