spikard 0.8.2 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +19 -10
- data/ext/spikard_rb/Cargo.lock +234 -162
- data/ext/spikard_rb/Cargo.toml +3 -3
- data/ext/spikard_rb/extconf.rb +4 -3
- data/lib/spikard/config.rb +88 -12
- data/lib/spikard/testing.rb +3 -1
- data/lib/spikard/version.rb +1 -1
- data/lib/spikard.rb +11 -0
- data/vendor/crates/spikard-bindings-shared/Cargo.toml +11 -6
- data/vendor/crates/spikard-bindings-shared/examples/config_extraction.rs +8 -8
- data/vendor/crates/spikard-bindings-shared/src/config_extractor.rs +63 -25
- data/vendor/crates/spikard-bindings-shared/src/conversion_traits.rs +20 -4
- data/vendor/crates/spikard-bindings-shared/src/di_traits.rs +10 -4
- data/vendor/crates/spikard-bindings-shared/src/error_response.rs +25 -22
- data/vendor/crates/spikard-bindings-shared/src/grpc_metadata.rs +14 -12
- data/vendor/crates/spikard-bindings-shared/src/handler_base.rs +24 -10
- data/vendor/crates/spikard-bindings-shared/src/json_conversion.rs +829 -0
- data/vendor/crates/spikard-bindings-shared/src/lazy_cache.rs +587 -0
- data/vendor/crates/spikard-bindings-shared/src/lib.rs +7 -0
- data/vendor/crates/spikard-bindings-shared/src/lifecycle_base.rs +17 -11
- data/vendor/crates/spikard-bindings-shared/src/lifecycle_executor.rs +51 -73
- data/vendor/crates/spikard-bindings-shared/src/response_builder.rs +442 -4
- data/vendor/crates/spikard-bindings-shared/src/response_interpreter.rs +944 -0
- data/vendor/crates/spikard-bindings-shared/src/test_client_base.rs +22 -10
- data/vendor/crates/spikard-bindings-shared/src/validation_helpers.rs +28 -10
- data/vendor/crates/spikard-bindings-shared/tests/config_extractor_behavior.rs +3 -2
- data/vendor/crates/spikard-bindings-shared/tests/error_response_edge_cases.rs +13 -13
- data/vendor/crates/spikard-bindings-shared/tests/{comprehensive_coverage.rs → full_coverage.rs} +10 -5
- data/vendor/crates/spikard-bindings-shared/tests/handler_base_integration.rs +14 -14
- data/vendor/crates/spikard-bindings-shared/tests/integration_tests.rs +669 -0
- data/vendor/crates/spikard-core/Cargo.toml +11 -3
- data/vendor/crates/spikard-core/src/bindings/response.rs +6 -9
- data/vendor/crates/spikard-core/src/debug.rs +2 -2
- data/vendor/crates/spikard-core/src/di/container.rs +2 -2
- data/vendor/crates/spikard-core/src/di/error.rs +1 -1
- data/vendor/crates/spikard-core/src/di/factory.rs +9 -5
- data/vendor/crates/spikard-core/src/di/graph.rs +1 -0
- data/vendor/crates/spikard-core/src/di/resolved.rs +25 -2
- data/vendor/crates/spikard-core/src/di/value.rs +2 -1
- data/vendor/crates/spikard-core/src/errors.rs +3 -0
- data/vendor/crates/spikard-core/src/http.rs +94 -18
- data/vendor/crates/spikard-core/src/lifecycle.rs +85 -61
- data/vendor/crates/spikard-core/src/parameters.rs +75 -54
- data/vendor/crates/spikard-core/src/problem.rs +19 -5
- data/vendor/crates/spikard-core/src/request_data.rs +16 -24
- data/vendor/crates/spikard-core/src/router.rs +26 -6
- data/vendor/crates/spikard-core/src/schema_registry.rs +25 -11
- data/vendor/crates/spikard-core/src/type_hints.rs +14 -7
- data/vendor/crates/spikard-core/src/validation/error_mapper.rs +30 -16
- data/vendor/crates/spikard-core/src/validation/mod.rs +46 -33
- data/vendor/crates/spikard-core/tests/di_dependency_defaults.rs +1 -1
- data/vendor/crates/spikard-core/tests/error_mapper.rs +2 -2
- data/vendor/crates/spikard-core/tests/parameters_edge_cases.rs +1 -1
- data/vendor/crates/spikard-core/tests/parameters_full.rs +1 -1
- data/vendor/crates/spikard-core/tests/parameters_schema_and_formats.rs +1 -1
- data/vendor/crates/spikard-core/tests/validation_coverage.rs +4 -4
- data/vendor/crates/spikard-http/Cargo.toml +11 -2
- data/vendor/crates/spikard-http/src/cors.rs +32 -11
- data/vendor/crates/spikard-http/src/di_handler.rs +12 -8
- data/vendor/crates/spikard-http/src/grpc/framing.rs +469 -0
- data/vendor/crates/spikard-http/src/grpc/handler.rs +887 -25
- data/vendor/crates/spikard-http/src/grpc/mod.rs +114 -22
- data/vendor/crates/spikard-http/src/grpc/service.rs +232 -2
- data/vendor/crates/spikard-http/src/grpc/streaming.rs +80 -2
- data/vendor/crates/spikard-http/src/handler_trait.rs +204 -27
- data/vendor/crates/spikard-http/src/handler_trait_tests.rs +15 -15
- data/vendor/crates/spikard-http/src/jsonrpc/http_handler.rs +2 -2
- data/vendor/crates/spikard-http/src/jsonrpc/router.rs +2 -2
- data/vendor/crates/spikard-http/src/lib.rs +1 -1
- data/vendor/crates/spikard-http/src/lifecycle/adapter.rs +2 -2
- data/vendor/crates/spikard-http/src/lifecycle.rs +4 -4
- data/vendor/crates/spikard-http/src/openapi/spec_generation.rs +2 -0
- data/vendor/crates/spikard-http/src/server/fast_router.rs +186 -0
- data/vendor/crates/spikard-http/src/server/grpc_routing.rs +324 -23
- data/vendor/crates/spikard-http/src/server/handler.rs +33 -22
- data/vendor/crates/spikard-http/src/server/lifecycle_execution.rs +21 -2
- data/vendor/crates/spikard-http/src/server/mod.rs +125 -20
- data/vendor/crates/spikard-http/src/server/request_extraction.rs +126 -44
- data/vendor/crates/spikard-http/src/server/routing_factory.rs +80 -69
- data/vendor/crates/spikard-http/tests/common/handlers.rs +2 -2
- data/vendor/crates/spikard-http/tests/common/test_builders.rs +12 -12
- data/vendor/crates/spikard-http/tests/di_handler_error_responses.rs +2 -2
- data/vendor/crates/spikard-http/tests/di_integration.rs +6 -6
- data/vendor/crates/spikard-http/tests/grpc_bidirectional_streaming.rs +430 -0
- data/vendor/crates/spikard-http/tests/grpc_client_streaming.rs +738 -0
- data/vendor/crates/spikard-http/tests/grpc_integration_test.rs +13 -9
- data/vendor/crates/spikard-http/tests/grpc_server_streaming.rs +974 -0
- data/vendor/crates/spikard-http/tests/lifecycle_execution.rs +2 -2
- data/vendor/crates/spikard-http/tests/request_extraction_full.rs +4 -4
- data/vendor/crates/spikard-http/tests/server_config_builder.rs +2 -2
- data/vendor/crates/spikard-http/tests/server_cors_preflight.rs +1 -0
- data/vendor/crates/spikard-http/tests/server_openapi_jsonrpc_static.rs +140 -0
- data/vendor/crates/spikard-rb/Cargo.toml +11 -1
- data/vendor/crates/spikard-rb/build.rs +1 -0
- data/vendor/crates/spikard-rb/src/conversion.rs +138 -4
- data/vendor/crates/spikard-rb/src/grpc/handler.rs +706 -229
- data/vendor/crates/spikard-rb/src/grpc/mod.rs +6 -2
- data/vendor/crates/spikard-rb/src/gvl.rs +2 -2
- data/vendor/crates/spikard-rb/src/handler.rs +169 -91
- data/vendor/crates/spikard-rb/src/lib.rs +502 -62
- data/vendor/crates/spikard-rb/src/lifecycle.rs +31 -3
- data/vendor/crates/spikard-rb/src/metadata/route_extraction.rs +108 -43
- data/vendor/crates/spikard-rb/src/request.rs +117 -20
- data/vendor/crates/spikard-rb/src/runtime/server_runner.rs +52 -25
- data/vendor/crates/spikard-rb/src/server.rs +23 -14
- data/vendor/crates/spikard-rb/src/testing/client.rs +5 -4
- data/vendor/crates/spikard-rb/src/testing/sse.rs +1 -36
- data/vendor/crates/spikard-rb/src/testing/websocket.rs +3 -38
- data/vendor/crates/spikard-rb/src/websocket.rs +32 -23
- data/vendor/crates/spikard-rb-macros/Cargo.toml +9 -1
- data/vendor/crates/spikard-rb-macros/src/lib.rs +4 -5
- metadata +14 -4
- data/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/mise.toml +0 -5
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.10.0/build/buildkitd.toml +0 -2
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
//! `LanguageLifecycleHook` to provide language-specific hook invocation, while
|
|
11
11
|
//! `LifecycleExecutor` handles the common logic:
|
|
12
12
|
//!
|
|
13
|
-
//! - Hook result type handling (Continue vs ShortCircuit)
|
|
13
|
+
//! - Hook result type handling (Continue vs `ShortCircuit`)
|
|
14
14
|
//! - Response/Request building from hook results
|
|
15
15
|
//! - Error handling and conversion
|
|
16
16
|
//!
|
|
@@ -73,7 +73,8 @@ pub struct RequestModifications {
|
|
|
73
73
|
|
|
74
74
|
impl HookResultData {
|
|
75
75
|
/// Create a Continue result (pass through)
|
|
76
|
-
|
|
76
|
+
#[must_use]
|
|
77
|
+
pub const fn continue_execution() -> Self {
|
|
77
78
|
Self {
|
|
78
79
|
continue_execution: true,
|
|
79
80
|
status_code: None,
|
|
@@ -84,7 +85,8 @@ impl HookResultData {
|
|
|
84
85
|
}
|
|
85
86
|
|
|
86
87
|
/// Create a short-circuit response result
|
|
87
|
-
|
|
88
|
+
#[must_use]
|
|
89
|
+
pub const fn short_circuit(status_code: u16, body: Vec<u8>, headers: Option<HashMap<String, String>>) -> Self {
|
|
88
90
|
Self {
|
|
89
91
|
continue_execution: false,
|
|
90
92
|
status_code: Some(status_code),
|
|
@@ -95,7 +97,8 @@ impl HookResultData {
|
|
|
95
97
|
}
|
|
96
98
|
|
|
97
99
|
/// Create a request modification result
|
|
98
|
-
|
|
100
|
+
#[must_use]
|
|
101
|
+
pub const fn modify_request(modifications: RequestModifications) -> Self {
|
|
99
102
|
Self {
|
|
100
103
|
continue_execution: true,
|
|
101
104
|
status_code: None,
|
|
@@ -117,6 +120,10 @@ pub trait LanguageLifecycleHook: Send + Sync {
|
|
|
117
120
|
/// Prepare hook data from the incoming request/response
|
|
118
121
|
///
|
|
119
122
|
/// This should convert axum HTTP types to language-specific representations.
|
|
123
|
+
///
|
|
124
|
+
/// # Errors
|
|
125
|
+
///
|
|
126
|
+
/// Returns an error if hook data preparation fails.
|
|
120
127
|
fn prepare_hook_data(&self, req: &Request<Body>) -> Result<Self::HookData, String>;
|
|
121
128
|
|
|
122
129
|
/// Invoke the language hook and return normalized result data
|
|
@@ -139,13 +146,17 @@ pub struct LifecycleExecutor<L: LanguageLifecycleHook> {
|
|
|
139
146
|
|
|
140
147
|
impl<L: LanguageLifecycleHook> LifecycleExecutor<L> {
|
|
141
148
|
/// Create a new executor for the given hook
|
|
142
|
-
pub fn new(hook: Arc<L>) -> Self {
|
|
149
|
+
pub const fn new(hook: Arc<L>) -> Self {
|
|
143
150
|
Self { hook }
|
|
144
151
|
}
|
|
145
152
|
|
|
146
153
|
/// Execute a request hook, handling Continue/ShortCircuit semantics
|
|
147
154
|
///
|
|
148
155
|
/// Returns either the modified request or a short-circuit response.
|
|
156
|
+
///
|
|
157
|
+
/// # Errors
|
|
158
|
+
///
|
|
159
|
+
/// Returns an error if hook execution or modification fails.
|
|
149
160
|
pub async fn execute_request_hook(
|
|
150
161
|
&self,
|
|
151
162
|
req: Request<Body>,
|
|
@@ -154,12 +165,12 @@ impl<L: LanguageLifecycleHook> LifecycleExecutor<L> {
|
|
|
154
165
|
let result = self.hook.invoke_hook(hook_data).await?;
|
|
155
166
|
|
|
156
167
|
if !result.continue_execution {
|
|
157
|
-
let response =
|
|
168
|
+
let response = Self::build_response_from_hook_result(&result)?;
|
|
158
169
|
return Ok(Err(response));
|
|
159
170
|
}
|
|
160
171
|
|
|
161
172
|
if let Some(modifications) = result.request_modifications {
|
|
162
|
-
let modified_req =
|
|
173
|
+
let modified_req = Self::apply_request_modifications(req, modifications)?;
|
|
163
174
|
Ok(Ok(modified_req))
|
|
164
175
|
} else {
|
|
165
176
|
Ok(Ok(req))
|
|
@@ -170,6 +181,11 @@ impl<L: LanguageLifecycleHook> LifecycleExecutor<L> {
|
|
|
170
181
|
///
|
|
171
182
|
/// Response hooks can only continue or modify the response,
|
|
172
183
|
/// never short-circuit.
|
|
184
|
+
/// Execute the lifecycle hook on an outgoing response
|
|
185
|
+
///
|
|
186
|
+
/// # Errors
|
|
187
|
+
///
|
|
188
|
+
/// Returns an error if hook execution or response building fails.
|
|
173
189
|
pub async fn execute_response_hook(&self, resp: Response<Body>) -> Result<Response<Body>, String> {
|
|
174
190
|
let (parts, body) = resp.into_parts();
|
|
175
191
|
let body_bytes = extract_body(body).await?;
|
|
@@ -178,7 +194,7 @@ impl<L: LanguageLifecycleHook> LifecycleExecutor<L> {
|
|
|
178
194
|
.method("GET")
|
|
179
195
|
.uri("/")
|
|
180
196
|
.body(Body::empty())
|
|
181
|
-
.map_err(|e| format!("Failed to build dummy request: {}"
|
|
197
|
+
.map_err(|e| format!("Failed to build dummy request: {e}"))?;
|
|
182
198
|
|
|
183
199
|
let hook_data = self.hook.prepare_hook_data(&dummy_req)?;
|
|
184
200
|
let result = self.hook.invoke_hook(hook_data).await?;
|
|
@@ -198,7 +214,7 @@ impl<L: LanguageLifecycleHook> LifecycleExecutor<L> {
|
|
|
198
214
|
}
|
|
199
215
|
}
|
|
200
216
|
|
|
201
|
-
for (name, value) in parts.headers
|
|
217
|
+
for (name, value) in &parts.headers {
|
|
202
218
|
let key_str = name.as_str().to_lowercase();
|
|
203
219
|
if !header_mod_keys.contains(&key_str) {
|
|
204
220
|
builder = builder.header(name, value);
|
|
@@ -208,7 +224,7 @@ impl<L: LanguageLifecycleHook> LifecycleExecutor<L> {
|
|
|
208
224
|
let body = modifications.body.unwrap_or(body_bytes);
|
|
209
225
|
return builder
|
|
210
226
|
.body(Body::from(body))
|
|
211
|
-
.map_err(|e| format!("Failed to build modified response: {}"
|
|
227
|
+
.map_err(|e| format!("Failed to build modified response: {e}"));
|
|
212
228
|
}
|
|
213
229
|
|
|
214
230
|
let mut builder = Response::builder().status(parts.status);
|
|
@@ -219,14 +235,14 @@ impl<L: LanguageLifecycleHook> LifecycleExecutor<L> {
|
|
|
219
235
|
}
|
|
220
236
|
builder
|
|
221
237
|
.body(Body::from(body_bytes))
|
|
222
|
-
.map_err(|e| format!("Failed to rebuild response: {}"
|
|
238
|
+
.map_err(|e| format!("Failed to rebuild response: {e}"))
|
|
223
239
|
}
|
|
224
240
|
|
|
225
241
|
/// Build an axum Response from hook result data
|
|
226
|
-
fn build_response_from_hook_result(
|
|
242
|
+
fn build_response_from_hook_result(result: &HookResultData) -> Result<Response<Body>, String> {
|
|
227
243
|
let status_code = result.status_code.unwrap_or(200);
|
|
228
244
|
let status =
|
|
229
|
-
StatusCode::from_u16(status_code).map_err(|e| format!("Invalid status code {}: {}"
|
|
245
|
+
StatusCode::from_u16(status_code).map_err(|e| format!("Invalid status code {status_code}: {e}"))?;
|
|
230
246
|
|
|
231
247
|
let mut builder = Response::builder().status(status);
|
|
232
248
|
|
|
@@ -236,11 +252,7 @@ impl<L: LanguageLifecycleHook> LifecycleExecutor<L> {
|
|
|
236
252
|
}
|
|
237
253
|
}
|
|
238
254
|
|
|
239
|
-
if !builder
|
|
240
|
-
.headers_ref()
|
|
241
|
-
.map(|h| h.contains_key("content-type"))
|
|
242
|
-
.unwrap_or(false)
|
|
243
|
-
{
|
|
255
|
+
if !builder.headers_ref().is_some_and(|h| h.contains_key("content-type")) {
|
|
244
256
|
builder = builder.header("content-type", "application/json");
|
|
245
257
|
}
|
|
246
258
|
|
|
@@ -248,43 +260,33 @@ impl<L: LanguageLifecycleHook> LifecycleExecutor<L> {
|
|
|
248
260
|
|
|
249
261
|
builder
|
|
250
262
|
.body(Body::from(body))
|
|
251
|
-
.map_err(|e| format!("Failed to build response: {}"
|
|
263
|
+
.map_err(|e| format!("Failed to build response: {e}"))
|
|
252
264
|
}
|
|
253
265
|
|
|
254
266
|
/// Apply request modifications to a request
|
|
255
|
-
fn apply_request_modifications(
|
|
256
|
-
&self,
|
|
257
|
-
req: Request<Body>,
|
|
258
|
-
mods: RequestModifications,
|
|
259
|
-
) -> Result<Request<Body>, String> {
|
|
267
|
+
fn apply_request_modifications(req: Request<Body>, mods: RequestModifications) -> Result<Request<Body>, String> {
|
|
260
268
|
let (mut parts, body) = req.into_parts();
|
|
261
269
|
|
|
262
270
|
if let Some(method) = &mods.method {
|
|
263
|
-
parts.method = method
|
|
264
|
-
.parse()
|
|
265
|
-
.map_err(|e| format!("Invalid method '{}': {}", method, e))?;
|
|
271
|
+
parts.method = method.parse().map_err(|e| format!("Invalid method '{method}': {e}"))?;
|
|
266
272
|
}
|
|
267
273
|
|
|
268
274
|
if let Some(path) = &mods.path {
|
|
269
|
-
parts.uri = path.parse().map_err(|e| format!("Invalid path '{}': {}"
|
|
275
|
+
parts.uri = path.parse().map_err(|e| format!("Invalid path '{path}': {e}"))?;
|
|
270
276
|
}
|
|
271
277
|
|
|
272
278
|
if let Some(new_headers) = &mods.headers {
|
|
273
279
|
for (key, value) in new_headers {
|
|
274
280
|
let header_name: http::header::HeaderName =
|
|
275
|
-
key.parse().map_err(|_| format!("Invalid header name: {}"
|
|
281
|
+
key.parse().map_err(|_| format!("Invalid header name: {key}"))?;
|
|
276
282
|
let header_value: http::header::HeaderValue = value
|
|
277
283
|
.parse()
|
|
278
|
-
.map_err(|_| format!("Invalid header value for {}: {}"
|
|
284
|
+
.map_err(|_| format!("Invalid header value for {key}: {value}"))?;
|
|
279
285
|
parts.headers.insert(header_name, header_value);
|
|
280
286
|
}
|
|
281
287
|
}
|
|
282
288
|
|
|
283
|
-
let body =
|
|
284
|
-
Body::from(new_body)
|
|
285
|
-
} else {
|
|
286
|
-
body
|
|
287
|
-
};
|
|
289
|
+
let body = mods.body.map_or(body, Body::from);
|
|
288
290
|
|
|
289
291
|
Ok(Request::from_parts(parts, body))
|
|
290
292
|
}
|
|
@@ -293,13 +295,17 @@ impl<L: LanguageLifecycleHook> LifecycleExecutor<L> {
|
|
|
293
295
|
/// Extract body bytes from an axum Body
|
|
294
296
|
///
|
|
295
297
|
/// This is a helper used by lifecycle executors to read response bodies.
|
|
298
|
+
///
|
|
299
|
+
/// # Errors
|
|
300
|
+
///
|
|
301
|
+
/// Returns an error if body collection fails.
|
|
296
302
|
pub async fn extract_body(body: Body) -> Result<Vec<u8>, String> {
|
|
297
303
|
use http_body_util::BodyExt;
|
|
298
304
|
|
|
299
305
|
let bytes = body
|
|
300
306
|
.collect()
|
|
301
307
|
.await
|
|
302
|
-
.map_err(|e| format!("Failed to read body: {}"
|
|
308
|
+
.map_err(|e| format!("Failed to read body: {e}"))?
|
|
303
309
|
.to_bytes();
|
|
304
310
|
Ok(bytes.to_vec())
|
|
305
311
|
}
|
|
@@ -338,7 +344,7 @@ mod tests {
|
|
|
338
344
|
body: None,
|
|
339
345
|
};
|
|
340
346
|
|
|
341
|
-
let result = HookResultData::modify_request(mods
|
|
347
|
+
let result = HookResultData::modify_request(mods);
|
|
342
348
|
assert!(result.continue_execution);
|
|
343
349
|
assert_eq!(result.status_code, None);
|
|
344
350
|
assert_eq!(
|
|
@@ -469,12 +475,8 @@ mod tests {
|
|
|
469
475
|
headers.insert("X-Custom".to_string(), "value".to_string());
|
|
470
476
|
|
|
471
477
|
let result = HookResultData::short_circuit(201, b"Created".to_vec(), Some(headers));
|
|
472
|
-
let hook = Arc::new(MockHook {
|
|
473
|
-
result: HookResultData::continue_execution(),
|
|
474
|
-
});
|
|
475
|
-
let executor = LifecycleExecutor::new(hook);
|
|
476
478
|
|
|
477
|
-
let response =
|
|
479
|
+
let response = LifecycleExecutor::<MockHook>::build_response_from_hook_result(&result).unwrap();
|
|
478
480
|
assert_eq!(response.status(), StatusCode::CREATED);
|
|
479
481
|
assert_eq!(response.headers().get("X-Custom").unwrap().to_str().unwrap(), "value");
|
|
480
482
|
}
|
|
@@ -482,12 +484,8 @@ mod tests {
|
|
|
482
484
|
#[tokio::test]
|
|
483
485
|
async fn test_build_response_from_hook_result_default_content_type() {
|
|
484
486
|
let result = HookResultData::short_circuit(200, b"{}".to_vec(), None);
|
|
485
|
-
let hook = Arc::new(MockHook {
|
|
486
|
-
result: HookResultData::continue_execution(),
|
|
487
|
-
});
|
|
488
|
-
let executor = LifecycleExecutor::new(hook);
|
|
489
487
|
|
|
490
|
-
let response =
|
|
488
|
+
let response = LifecycleExecutor::<MockHook>::build_response_from_hook_result(&result).unwrap();
|
|
491
489
|
assert_eq!(
|
|
492
490
|
response.headers().get("content-type").unwrap().to_str().unwrap(),
|
|
493
491
|
"application/json"
|
|
@@ -502,13 +500,9 @@ mod tests {
|
|
|
502
500
|
headers: None,
|
|
503
501
|
body: None,
|
|
504
502
|
};
|
|
505
|
-
let hook = Arc::new(MockHook {
|
|
506
|
-
result: HookResultData::continue_execution(),
|
|
507
|
-
});
|
|
508
|
-
let executor = LifecycleExecutor::new(hook);
|
|
509
503
|
|
|
510
504
|
let req = Request::builder().method("GET").body(Body::empty()).unwrap();
|
|
511
|
-
let modified =
|
|
505
|
+
let modified = LifecycleExecutor::<MockHook>::apply_request_modifications(req, mods).unwrap();
|
|
512
506
|
|
|
513
507
|
assert_eq!(modified.method(), "PATCH");
|
|
514
508
|
}
|
|
@@ -521,13 +515,9 @@ mod tests {
|
|
|
521
515
|
headers: None,
|
|
522
516
|
body: None,
|
|
523
517
|
};
|
|
524
|
-
let hook = Arc::new(MockHook {
|
|
525
|
-
result: HookResultData::continue_execution(),
|
|
526
|
-
});
|
|
527
|
-
let executor = LifecycleExecutor::new(hook);
|
|
528
518
|
|
|
529
519
|
let req = Request::builder().uri("/api/v1/users").body(Body::empty()).unwrap();
|
|
530
|
-
let modified =
|
|
520
|
+
let modified = LifecycleExecutor::<MockHook>::apply_request_modifications(req, mods).unwrap();
|
|
531
521
|
|
|
532
522
|
assert_eq!(modified.uri().path(), "/api/v2/users");
|
|
533
523
|
}
|
|
@@ -543,13 +533,9 @@ mod tests {
|
|
|
543
533
|
headers: Some(new_headers),
|
|
544
534
|
body: None,
|
|
545
535
|
};
|
|
546
|
-
let hook = Arc::new(MockHook {
|
|
547
|
-
result: HookResultData::continue_execution(),
|
|
548
|
-
});
|
|
549
|
-
let executor = LifecycleExecutor::new(hook);
|
|
550
536
|
|
|
551
537
|
let req = Request::builder().body(Body::empty()).unwrap();
|
|
552
|
-
let modified =
|
|
538
|
+
let modified = LifecycleExecutor::<MockHook>::apply_request_modifications(req, mods).unwrap();
|
|
553
539
|
|
|
554
540
|
assert_eq!(
|
|
555
541
|
modified.headers().get("Authorization").unwrap().to_str().unwrap(),
|
|
@@ -566,13 +552,9 @@ mod tests {
|
|
|
566
552
|
headers: None,
|
|
567
553
|
body: Some(new_body.clone()),
|
|
568
554
|
};
|
|
569
|
-
let hook = Arc::new(MockHook {
|
|
570
|
-
result: HookResultData::continue_execution(),
|
|
571
|
-
});
|
|
572
|
-
let executor = LifecycleExecutor::new(hook);
|
|
573
555
|
|
|
574
556
|
let req = Request::builder().body(Body::from("original body")).unwrap();
|
|
575
|
-
let modified =
|
|
557
|
+
let modified = LifecycleExecutor::<MockHook>::apply_request_modifications(req, mods).unwrap();
|
|
576
558
|
|
|
577
559
|
let body_bytes = extract_body(modified.into_body()).await.unwrap();
|
|
578
560
|
assert_eq!(body_bytes, new_body);
|
|
@@ -581,18 +563,14 @@ mod tests {
|
|
|
581
563
|
#[tokio::test]
|
|
582
564
|
async fn test_apply_request_modifications_invalid_method() {
|
|
583
565
|
let mods = RequestModifications {
|
|
584
|
-
method: Some(
|
|
566
|
+
method: Some(String::new()),
|
|
585
567
|
path: None,
|
|
586
568
|
headers: None,
|
|
587
569
|
body: None,
|
|
588
570
|
};
|
|
589
|
-
let hook = Arc::new(MockHook {
|
|
590
|
-
result: HookResultData::continue_execution(),
|
|
591
|
-
});
|
|
592
|
-
let executor = LifecycleExecutor::new(hook);
|
|
593
571
|
|
|
594
572
|
let req = Request::builder().body(Body::empty()).unwrap();
|
|
595
|
-
let result =
|
|
573
|
+
let result = LifecycleExecutor::<MockHook>::apply_request_modifications(req, mods);
|
|
596
574
|
|
|
597
575
|
assert!(result.is_err());
|
|
598
576
|
assert!(result.unwrap_err().contains("Invalid method"));
|