spikard 0.12.0 → 0.15.2
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/Steepfile +6 -0
- data/ext/spikard_rb/extconf.rb +1 -2
- data/ext/spikard_rb/{Cargo.lock → native/Cargo.lock} +897 -451
- data/ext/spikard_rb/native/Cargo.toml +24 -0
- data/ext/spikard_rb/src/lib.rs +5366 -3
- data/lib/spikard/native.rb +86 -0
- data/lib/spikard/version.rb +6 -1
- data/lib/spikard.rb +8 -45
- data/lib/spikard_rb.so +0 -0
- data/sig/types.rbs +427 -0
- metadata +14 -242
- data/LICENSE +0 -1
- data/README.md +0 -267
- data/ext/spikard_rb/Cargo.toml +0 -17
- data/lib/spikard/app.rb +0 -428
- data/lib/spikard/background.rb +0 -58
- data/lib/spikard/config.rb +0 -506
- data/lib/spikard/converters.rb +0 -13
- data/lib/spikard/grpc.rb +0 -182
- data/lib/spikard/handler_wrapper.rb +0 -113
- data/lib/spikard/provide.rb +0 -214
- data/lib/spikard/response.rb +0 -173
- data/lib/spikard/schema.rb +0 -243
- data/lib/spikard/sse.rb +0 -111
- data/lib/spikard/streaming_response.rb +0 -44
- data/lib/spikard/testing.rb +0 -432
- data/lib/spikard/upload_file.rb +0 -131
- data/lib/spikard/websocket.rb +0 -59
- data/sig/spikard.rbs +0 -719
- data/vendor/crates/spikard-bindings-shared/Cargo.toml +0 -80
- data/vendor/crates/spikard-bindings-shared/examples/config_extraction.rs +0 -132
- data/vendor/crates/spikard-bindings-shared/src/config_extractor.rs +0 -905
- data/vendor/crates/spikard-bindings-shared/src/conversion_traits.rs +0 -210
- data/vendor/crates/spikard-bindings-shared/src/di_traits.rs +0 -252
- data/vendor/crates/spikard-bindings-shared/src/error_response.rs +0 -404
- data/vendor/crates/spikard-bindings-shared/src/grpc_metadata.rs +0 -199
- data/vendor/crates/spikard-bindings-shared/src/handler_base.rs +0 -252
- data/vendor/crates/spikard-bindings-shared/src/json_conversion.rs +0 -829
- data/vendor/crates/spikard-bindings-shared/src/lazy_cache.rs +0 -587
- data/vendor/crates/spikard-bindings-shared/src/lib.rs +0 -33
- data/vendor/crates/spikard-bindings-shared/src/lifecycle_base.rs +0 -298
- data/vendor/crates/spikard-bindings-shared/src/lifecycle_executor.rs +0 -594
- data/vendor/crates/spikard-bindings-shared/src/response_builder.rs +0 -743
- data/vendor/crates/spikard-bindings-shared/src/response_interpreter.rs +0 -944
- data/vendor/crates/spikard-bindings-shared/src/test_client_base.rs +0 -260
- data/vendor/crates/spikard-bindings-shared/src/validation_helpers.rs +0 -369
- data/vendor/crates/spikard-bindings-shared/tests/config_extractor_behavior.rs +0 -192
- data/vendor/crates/spikard-bindings-shared/tests/error_response_edge_cases.rs +0 -383
- data/vendor/crates/spikard-bindings-shared/tests/full_coverage.rs +0 -459
- data/vendor/crates/spikard-bindings-shared/tests/handler_base_integration.rs +0 -280
- data/vendor/crates/spikard-bindings-shared/tests/integration_tests.rs +0 -669
- data/vendor/crates/spikard-core/Cargo.toml +0 -60
- data/vendor/crates/spikard-core/src/bindings/mod.rs +0 -3
- data/vendor/crates/spikard-core/src/bindings/response.rs +0 -130
- data/vendor/crates/spikard-core/src/debug.rs +0 -127
- data/vendor/crates/spikard-core/src/di/container.rs +0 -702
- data/vendor/crates/spikard-core/src/di/dependency.rs +0 -273
- data/vendor/crates/spikard-core/src/di/error.rs +0 -118
- data/vendor/crates/spikard-core/src/di/factory.rs +0 -538
- data/vendor/crates/spikard-core/src/di/graph.rs +0 -507
- data/vendor/crates/spikard-core/src/di/mod.rs +0 -192
- data/vendor/crates/spikard-core/src/di/resolved.rs +0 -428
- data/vendor/crates/spikard-core/src/di/value.rs +0 -282
- data/vendor/crates/spikard-core/src/errors.rs +0 -72
- data/vendor/crates/spikard-core/src/http.rs +0 -492
- data/vendor/crates/spikard-core/src/lib.rs +0 -29
- data/vendor/crates/spikard-core/src/lifecycle.rs +0 -1273
- data/vendor/crates/spikard-core/src/metadata.rs +0 -378
- data/vendor/crates/spikard-core/src/parameters.rs +0 -2546
- data/vendor/crates/spikard-core/src/problem.rs +0 -358
- data/vendor/crates/spikard-core/src/request_data.rs +0 -1146
- data/vendor/crates/spikard-core/src/router.rs +0 -530
- data/vendor/crates/spikard-core/src/schema_registry.rs +0 -197
- data/vendor/crates/spikard-core/src/type_hints.rs +0 -311
- data/vendor/crates/spikard-core/src/validation/error_mapper.rs +0 -710
- data/vendor/crates/spikard-core/src/validation/mod.rs +0 -470
- data/vendor/crates/spikard-core/tests/bindings_response_tests.rs +0 -136
- data/vendor/crates/spikard-core/tests/di_dependency_defaults.rs +0 -37
- data/vendor/crates/spikard-core/tests/error_mapper.rs +0 -761
- data/vendor/crates/spikard-core/tests/parameters_edge_cases.rs +0 -106
- data/vendor/crates/spikard-core/tests/parameters_full.rs +0 -701
- data/vendor/crates/spikard-core/tests/parameters_schema_and_formats.rs +0 -301
- data/vendor/crates/spikard-core/tests/request_data_roundtrip.rs +0 -67
- data/vendor/crates/spikard-core/tests/validation_coverage.rs +0 -250
- data/vendor/crates/spikard-core/tests/validation_error_paths.rs +0 -45
- data/vendor/crates/spikard-http/Cargo.toml +0 -87
- data/vendor/crates/spikard-http/examples/sse-notifications.rs +0 -148
- data/vendor/crates/spikard-http/examples/websocket-chat.rs +0 -92
- data/vendor/crates/spikard-http/src/auth.rs +0 -301
- data/vendor/crates/spikard-http/src/background.rs +0 -1860
- data/vendor/crates/spikard-http/src/bindings/mod.rs +0 -3
- data/vendor/crates/spikard-http/src/bindings/response.rs +0 -1
- data/vendor/crates/spikard-http/src/body_metadata.rs +0 -8
- data/vendor/crates/spikard-http/src/cors.rs +0 -1026
- data/vendor/crates/spikard-http/src/debug.rs +0 -128
- data/vendor/crates/spikard-http/src/di_handler.rs +0 -1672
- data/vendor/crates/spikard-http/src/grpc/framing.rs +0 -469
- data/vendor/crates/spikard-http/src/grpc/handler.rs +0 -1122
- data/vendor/crates/spikard-http/src/grpc/mod.rs +0 -434
- data/vendor/crates/spikard-http/src/grpc/service.rs +0 -622
- data/vendor/crates/spikard-http/src/grpc/streaming.rs +0 -319
- data/vendor/crates/spikard-http/src/handler_response.rs +0 -901
- data/vendor/crates/spikard-http/src/handler_trait.rs +0 -1015
- data/vendor/crates/spikard-http/src/handler_trait_tests.rs +0 -290
- data/vendor/crates/spikard-http/src/jsonrpc/http_handler.rs +0 -502
- data/vendor/crates/spikard-http/src/jsonrpc/method_registry.rs +0 -648
- data/vendor/crates/spikard-http/src/jsonrpc/mod.rs +0 -58
- data/vendor/crates/spikard-http/src/jsonrpc/protocol.rs +0 -1207
- data/vendor/crates/spikard-http/src/jsonrpc/router.rs +0 -2262
- data/vendor/crates/spikard-http/src/lib.rs +0 -548
- data/vendor/crates/spikard-http/src/lifecycle/adapter.rs +0 -230
- data/vendor/crates/spikard-http/src/lifecycle.rs +0 -1193
- data/vendor/crates/spikard-http/src/middleware/mod.rs +0 -560
- data/vendor/crates/spikard-http/src/middleware/multipart.rs +0 -912
- data/vendor/crates/spikard-http/src/middleware/urlencoded.rs +0 -513
- data/vendor/crates/spikard-http/src/middleware/validation.rs +0 -768
- data/vendor/crates/spikard-http/src/openapi/mod.rs +0 -309
- data/vendor/crates/spikard-http/src/openapi/parameter_extraction.rs +0 -535
- data/vendor/crates/spikard-http/src/openapi/schema_conversion.rs +0 -1363
- data/vendor/crates/spikard-http/src/openapi/spec_generation.rs +0 -667
- data/vendor/crates/spikard-http/src/query_parser.rs +0 -793
- data/vendor/crates/spikard-http/src/response.rs +0 -720
- data/vendor/crates/spikard-http/src/server/fast_router.rs +0 -186
- data/vendor/crates/spikard-http/src/server/grpc_routing.rs +0 -858
- data/vendor/crates/spikard-http/src/server/handler.rs +0 -1661
- data/vendor/crates/spikard-http/src/server/lifecycle_execution.rs +0 -253
- data/vendor/crates/spikard-http/src/server/mod.rs +0 -1649
- data/vendor/crates/spikard-http/src/server/request_extraction.rs +0 -871
- data/vendor/crates/spikard-http/src/server/routing_factory.rs +0 -618
- data/vendor/crates/spikard-http/src/sse.rs +0 -1409
- data/vendor/crates/spikard-http/src/testing/form.rs +0 -52
- data/vendor/crates/spikard-http/src/testing/multipart.rs +0 -64
- data/vendor/crates/spikard-http/src/testing/test_client.rs +0 -787
- data/vendor/crates/spikard-http/src/testing.rs +0 -617
- data/vendor/crates/spikard-http/src/websocket.rs +0 -1477
- data/vendor/crates/spikard-http/tests/auth_integration.rs +0 -645
- data/vendor/crates/spikard-http/tests/background_behavior.rs +0 -832
- data/vendor/crates/spikard-http/tests/common/grpc_helpers.rs +0 -1012
- data/vendor/crates/spikard-http/tests/common/handlers.rs +0 -309
- data/vendor/crates/spikard-http/tests/common/mod.rs +0 -33
- data/vendor/crates/spikard-http/tests/common/test_builders.rs +0 -628
- data/vendor/crates/spikard-http/tests/di_handler_error_responses.rs +0 -162
- data/vendor/crates/spikard-http/tests/di_integration.rs +0 -192
- data/vendor/crates/spikard-http/tests/doc_snippets.rs +0 -5
- data/vendor/crates/spikard-http/tests/grpc_bidirectional_streaming.rs +0 -430
- data/vendor/crates/spikard-http/tests/grpc_client_streaming.rs +0 -738
- data/vendor/crates/spikard-http/tests/grpc_error_handling_test.rs +0 -652
- data/vendor/crates/spikard-http/tests/grpc_integration_test.rs +0 -334
- data/vendor/crates/spikard-http/tests/grpc_metadata_test.rs +0 -532
- data/vendor/crates/spikard-http/tests/grpc_server_integration.rs +0 -495
- data/vendor/crates/spikard-http/tests/grpc_server_streaming.rs +0 -974
- data/vendor/crates/spikard-http/tests/lifecycle_execution.rs +0 -1093
- data/vendor/crates/spikard-http/tests/middleware_stack_integration.rs +0 -389
- data/vendor/crates/spikard-http/tests/multipart_behavior.rs +0 -656
- data/vendor/crates/spikard-http/tests/request_extraction_full.rs +0 -513
- data/vendor/crates/spikard-http/tests/server_auth_middleware_behavior.rs +0 -328
- data/vendor/crates/spikard-http/tests/server_config_builder.rs +0 -314
- data/vendor/crates/spikard-http/tests/server_configured_router_behavior.rs +0 -200
- data/vendor/crates/spikard-http/tests/server_cors_preflight.rs +0 -83
- data/vendor/crates/spikard-http/tests/server_handler_wrappers.rs +0 -464
- data/vendor/crates/spikard-http/tests/server_method_router_additional_behavior.rs +0 -286
- data/vendor/crates/spikard-http/tests/server_method_router_coverage.rs +0 -118
- data/vendor/crates/spikard-http/tests/server_middleware_behavior.rs +0 -99
- data/vendor/crates/spikard-http/tests/server_middleware_branches.rs +0 -204
- data/vendor/crates/spikard-http/tests/server_openapi_jsonrpc_static.rs +0 -421
- data/vendor/crates/spikard-http/tests/server_router_behavior.rs +0 -121
- data/vendor/crates/spikard-http/tests/sse_behavior.rs +0 -620
- data/vendor/crates/spikard-http/tests/sse_full_behavior.rs +0 -584
- data/vendor/crates/spikard-http/tests/sse_handler_behavior.rs +0 -130
- data/vendor/crates/spikard-http/tests/test_client_requests.rs +0 -167
- data/vendor/crates/spikard-http/tests/testing_helpers.rs +0 -87
- data/vendor/crates/spikard-http/tests/testing_module_coverage.rs +0 -155
- data/vendor/crates/spikard-http/tests/urlencoded_content_type.rs +0 -82
- data/vendor/crates/spikard-http/tests/websocket_behavior.rs +0 -663
- data/vendor/crates/spikard-http/tests/websocket_full_behavior.rs +0 -440
- data/vendor/crates/spikard-http/tests/websocket_integration.rs +0 -150
- data/vendor/crates/spikard-rb/Cargo.toml +0 -68
- data/vendor/crates/spikard-rb/build.rs +0 -200
- data/vendor/crates/spikard-rb/src/background.rs +0 -63
- data/vendor/crates/spikard-rb/src/config/mod.rs +0 -5
- data/vendor/crates/spikard-rb/src/config/server_config.rs +0 -401
- data/vendor/crates/spikard-rb/src/conversion.rs +0 -688
- data/vendor/crates/spikard-rb/src/di/builder.rs +0 -100
- data/vendor/crates/spikard-rb/src/di/mod.rs +0 -375
- data/vendor/crates/spikard-rb/src/grpc/handler.rs +0 -834
- data/vendor/crates/spikard-rb/src/grpc/mod.rs +0 -13
- data/vendor/crates/spikard-rb/src/gvl.rs +0 -80
- data/vendor/crates/spikard-rb/src/handler.rs +0 -699
- data/vendor/crates/spikard-rb/src/integration/mod.rs +0 -3
- data/vendor/crates/spikard-rb/src/lib.rs +0 -2264
- data/vendor/crates/spikard-rb/src/lifecycle.rs +0 -303
- data/vendor/crates/spikard-rb/src/metadata/mod.rs +0 -5
- data/vendor/crates/spikard-rb/src/metadata/route_extraction.rs +0 -507
- data/vendor/crates/spikard-rb/src/request.rs +0 -439
- data/vendor/crates/spikard-rb/src/runtime/mod.rs +0 -5
- data/vendor/crates/spikard-rb/src/runtime/server_runner.rs +0 -344
- data/vendor/crates/spikard-rb/src/server.rs +0 -307
- data/vendor/crates/spikard-rb/src/sse.rs +0 -231
- data/vendor/crates/spikard-rb/src/testing/client.rs +0 -698
- data/vendor/crates/spikard-rb/src/testing/mod.rs +0 -7
- data/vendor/crates/spikard-rb/src/testing/sse.rs +0 -108
- data/vendor/crates/spikard-rb/src/testing/websocket.rs +0 -573
- data/vendor/crates/spikard-rb/src/websocket.rs +0 -475
- data/vendor/crates/spikard-rb-macros/Cargo.toml +0 -25
- data/vendor/crates/spikard-rb-macros/src/lib.rs +0 -51
|
@@ -1,618 +0,0 @@
|
|
|
1
|
-
//! Method routing factory for consolidating HTTP method handler creation.
|
|
2
|
-
//!
|
|
3
|
-
//! This module provides a factory pattern to eliminate duplication in the
|
|
4
|
-
//! create_method_router function. It handles:
|
|
5
|
-
//! - Different HTTP methods (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, TRACE)
|
|
6
|
-
//! - Both path variants (with and without path parameters)
|
|
7
|
-
//! - Handler wrapping and request data extraction
|
|
8
|
-
//! - Lifecycle hook integration
|
|
9
|
-
|
|
10
|
-
use crate::handler_trait::{Handler, HandlerResult, RequestData};
|
|
11
|
-
use axum::body::Body;
|
|
12
|
-
use axum::extract::{Path, Request as AxumRequest};
|
|
13
|
-
use axum::http::Request;
|
|
14
|
-
use axum::routing::MethodRouter;
|
|
15
|
-
use bytes::Bytes;
|
|
16
|
-
use std::collections::HashMap;
|
|
17
|
-
use std::sync::Arc;
|
|
18
|
-
|
|
19
|
-
use super::lifecycle_execution;
|
|
20
|
-
use super::request_extraction;
|
|
21
|
-
|
|
22
|
-
/// Execute handler with optional lifecycle hooks.
|
|
23
|
-
///
|
|
24
|
-
/// Performance: Checks if hooks are present and non-empty before incurring
|
|
25
|
-
/// the overhead of lifecycle execution. Most requests don't have hooks.
|
|
26
|
-
#[inline]
|
|
27
|
-
async fn call_with_optional_hooks(
|
|
28
|
-
req: Request<Body>,
|
|
29
|
-
request_data: RequestData,
|
|
30
|
-
handler: Arc<dyn Handler>,
|
|
31
|
-
hooks: Option<Arc<crate::LifecycleHooks>>,
|
|
32
|
-
) -> HandlerResult {
|
|
33
|
-
// Performance: Fast path for requests without hooks (common case).
|
|
34
|
-
// Only invoke lifecycle execution when hooks are actually registered.
|
|
35
|
-
if hooks.as_ref().is_some_and(|h| !h.is_empty()) {
|
|
36
|
-
lifecycle_execution::execute_with_lifecycle_hooks(req, request_data, handler, hooks).await
|
|
37
|
-
} else {
|
|
38
|
-
handler.call(req, request_data).await
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/// HTTP method type enumeration for routing
|
|
43
|
-
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
44
|
-
pub enum HttpMethod {
|
|
45
|
-
Get,
|
|
46
|
-
Post,
|
|
47
|
-
Put,
|
|
48
|
-
Patch,
|
|
49
|
-
Delete,
|
|
50
|
-
Head,
|
|
51
|
-
Trace,
|
|
52
|
-
Options,
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
impl HttpMethod {
|
|
56
|
-
/// Parse from string representation (e.g., "GET", "POST")
|
|
57
|
-
pub fn from_str(s: &str) -> Option<Self> {
|
|
58
|
-
match s {
|
|
59
|
-
"GET" => Some(HttpMethod::Get),
|
|
60
|
-
"POST" => Some(HttpMethod::Post),
|
|
61
|
-
"PUT" => Some(HttpMethod::Put),
|
|
62
|
-
"PATCH" => Some(HttpMethod::Patch),
|
|
63
|
-
"DELETE" => Some(HttpMethod::Delete),
|
|
64
|
-
"HEAD" => Some(HttpMethod::Head),
|
|
65
|
-
"TRACE" => Some(HttpMethod::Trace),
|
|
66
|
-
"OPTIONS" => Some(HttpMethod::Options),
|
|
67
|
-
_ => None,
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/// Check if this method typically has a request body
|
|
72
|
-
pub fn expects_body(&self) -> bool {
|
|
73
|
-
matches!(self, HttpMethod::Post | HttpMethod::Put | HttpMethod::Patch)
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/// Factory for creating method routers
|
|
78
|
-
pub struct MethodRouterFactory;
|
|
79
|
-
|
|
80
|
-
impl MethodRouterFactory {
|
|
81
|
-
/// Create a method router for the given HTTP method
|
|
82
|
-
///
|
|
83
|
-
/// # Arguments
|
|
84
|
-
///
|
|
85
|
-
/// * `method` - HTTP method string (e.g., "GET", "POST")
|
|
86
|
-
/// * `has_path_params` - Whether the route has path parameters
|
|
87
|
-
/// * `handler` - The request handler
|
|
88
|
-
/// * `hooks` - Optional lifecycle hooks
|
|
89
|
-
///
|
|
90
|
-
/// # Returns
|
|
91
|
-
///
|
|
92
|
-
/// A configured MethodRouter or an error if the method is unsupported
|
|
93
|
-
pub fn create(
|
|
94
|
-
method: &str,
|
|
95
|
-
has_path_params: bool,
|
|
96
|
-
handler: Arc<dyn Handler>,
|
|
97
|
-
hooks: Option<Arc<crate::LifecycleHooks>>,
|
|
98
|
-
include_raw_query_params: bool,
|
|
99
|
-
) -> Result<MethodRouter, String> {
|
|
100
|
-
let http_method = HttpMethod::from_str(method)
|
|
101
|
-
.ok_or_else(|| format!("[spikard-router] unsupported HTTP method: {}", method))?;
|
|
102
|
-
|
|
103
|
-
let include_query_params_json = !handler.prefers_parameter_extraction();
|
|
104
|
-
let include_headers = handler.wants_headers();
|
|
105
|
-
let include_cookies = handler.wants_cookies();
|
|
106
|
-
|
|
107
|
-
Ok(if has_path_params {
|
|
108
|
-
Self::create_with_path_params(
|
|
109
|
-
http_method,
|
|
110
|
-
handler,
|
|
111
|
-
hooks,
|
|
112
|
-
include_raw_query_params,
|
|
113
|
-
include_query_params_json,
|
|
114
|
-
include_headers,
|
|
115
|
-
include_cookies,
|
|
116
|
-
)
|
|
117
|
-
} else {
|
|
118
|
-
Self::create_without_path_params(
|
|
119
|
-
http_method,
|
|
120
|
-
handler,
|
|
121
|
-
hooks,
|
|
122
|
-
include_raw_query_params,
|
|
123
|
-
include_query_params_json,
|
|
124
|
-
include_headers,
|
|
125
|
-
include_cookies,
|
|
126
|
-
)
|
|
127
|
-
})
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/// Create a method router for a route with path parameters
|
|
131
|
-
///
|
|
132
|
-
/// Performance: Each match arm only clones the Arc when needed for that specific
|
|
133
|
-
/// HTTP method, avoiding redundant clones at the function level.
|
|
134
|
-
fn create_with_path_params(
|
|
135
|
-
method: HttpMethod,
|
|
136
|
-
handler: Arc<dyn Handler>,
|
|
137
|
-
hooks: Option<Arc<crate::LifecycleHooks>>,
|
|
138
|
-
include_raw_query_params: bool,
|
|
139
|
-
include_query_params_json: bool,
|
|
140
|
-
include_headers: bool,
|
|
141
|
-
include_cookies: bool,
|
|
142
|
-
) -> MethodRouter {
|
|
143
|
-
// Performance: Removed redundant outer clones. Each match arm clones only when needed.
|
|
144
|
-
let without_body_options = request_extraction::WithoutBodyExtractionOptions {
|
|
145
|
-
include_raw_query_params,
|
|
146
|
-
include_query_params_json,
|
|
147
|
-
include_headers,
|
|
148
|
-
include_cookies,
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
if method.expects_body() {
|
|
152
|
-
match method {
|
|
153
|
-
HttpMethod::Post => {
|
|
154
|
-
// Performance: Clone directly from parameters, avoiding intermediate clone.
|
|
155
|
-
let handler_for_closure = handler.clone();
|
|
156
|
-
let hooks_for_closure = hooks.clone();
|
|
157
|
-
axum::routing::post(move |path_params: Path<HashMap<String, String>>, req: AxumRequest| {
|
|
158
|
-
let handler = handler_for_closure.clone();
|
|
159
|
-
let hooks = hooks_for_closure.clone();
|
|
160
|
-
async move {
|
|
161
|
-
let (parts, body) = req.into_parts();
|
|
162
|
-
let request_data = request_extraction::create_request_data_with_body(
|
|
163
|
-
&parts,
|
|
164
|
-
path_params.0,
|
|
165
|
-
body,
|
|
166
|
-
include_raw_query_params,
|
|
167
|
-
include_query_params_json,
|
|
168
|
-
include_headers,
|
|
169
|
-
include_cookies,
|
|
170
|
-
)
|
|
171
|
-
.await?;
|
|
172
|
-
let mut req = Request::from_parts(
|
|
173
|
-
parts,
|
|
174
|
-
Body::from(request_data.raw_body.clone().unwrap_or_else(Bytes::new)),
|
|
175
|
-
);
|
|
176
|
-
if handler.wants_request_extensions() {
|
|
177
|
-
req.extensions_mut().insert(Arc::new(request_data.clone()));
|
|
178
|
-
}
|
|
179
|
-
call_with_optional_hooks(req, request_data, handler, hooks).await
|
|
180
|
-
}
|
|
181
|
-
})
|
|
182
|
-
}
|
|
183
|
-
HttpMethod::Put => {
|
|
184
|
-
let handler_for_closure = handler.clone();
|
|
185
|
-
let hooks_for_closure = hooks.clone();
|
|
186
|
-
axum::routing::put(move |path_params: Path<HashMap<String, String>>, req: AxumRequest| {
|
|
187
|
-
let handler = handler_for_closure.clone();
|
|
188
|
-
let hooks = hooks_for_closure.clone();
|
|
189
|
-
async move {
|
|
190
|
-
let (parts, body) = req.into_parts();
|
|
191
|
-
let request_data = request_extraction::create_request_data_with_body(
|
|
192
|
-
&parts,
|
|
193
|
-
path_params.0,
|
|
194
|
-
body,
|
|
195
|
-
include_raw_query_params,
|
|
196
|
-
include_query_params_json,
|
|
197
|
-
include_headers,
|
|
198
|
-
include_cookies,
|
|
199
|
-
)
|
|
200
|
-
.await?;
|
|
201
|
-
let mut req = Request::from_parts(
|
|
202
|
-
parts,
|
|
203
|
-
Body::from(request_data.raw_body.clone().unwrap_or_else(Bytes::new)),
|
|
204
|
-
);
|
|
205
|
-
if handler.wants_request_extensions() {
|
|
206
|
-
req.extensions_mut().insert(Arc::new(request_data.clone()));
|
|
207
|
-
}
|
|
208
|
-
call_with_optional_hooks(req, request_data, handler, hooks).await
|
|
209
|
-
}
|
|
210
|
-
})
|
|
211
|
-
}
|
|
212
|
-
HttpMethod::Patch => {
|
|
213
|
-
let handler_for_closure = handler.clone();
|
|
214
|
-
let hooks_for_closure = hooks.clone();
|
|
215
|
-
axum::routing::patch(move |path_params: Path<HashMap<String, String>>, req: AxumRequest| {
|
|
216
|
-
let handler = handler_for_closure.clone();
|
|
217
|
-
let hooks = hooks_for_closure.clone();
|
|
218
|
-
async move {
|
|
219
|
-
let (parts, body) = req.into_parts();
|
|
220
|
-
let request_data = request_extraction::create_request_data_with_body(
|
|
221
|
-
&parts,
|
|
222
|
-
path_params.0,
|
|
223
|
-
body,
|
|
224
|
-
include_raw_query_params,
|
|
225
|
-
include_query_params_json,
|
|
226
|
-
include_headers,
|
|
227
|
-
include_cookies,
|
|
228
|
-
)
|
|
229
|
-
.await?;
|
|
230
|
-
let mut req = Request::from_parts(
|
|
231
|
-
parts,
|
|
232
|
-
Body::from(request_data.raw_body.clone().unwrap_or_else(Bytes::new)),
|
|
233
|
-
);
|
|
234
|
-
if handler.wants_request_extensions() {
|
|
235
|
-
req.extensions_mut().insert(Arc::new(request_data.clone()));
|
|
236
|
-
}
|
|
237
|
-
call_with_optional_hooks(req, request_data, handler, hooks).await
|
|
238
|
-
}
|
|
239
|
-
})
|
|
240
|
-
}
|
|
241
|
-
_ => MethodRouter::new(),
|
|
242
|
-
}
|
|
243
|
-
} else {
|
|
244
|
-
match method {
|
|
245
|
-
HttpMethod::Get => {
|
|
246
|
-
let handler_for_closure = handler.clone();
|
|
247
|
-
let hooks_for_closure = hooks.clone();
|
|
248
|
-
axum::routing::get(move |path_params: Path<HashMap<String, String>>, req: AxumRequest| {
|
|
249
|
-
let handler = handler_for_closure.clone();
|
|
250
|
-
let hooks = hooks_for_closure.clone();
|
|
251
|
-
async move {
|
|
252
|
-
let request_data = request_extraction::create_request_data_without_body(
|
|
253
|
-
req.uri(),
|
|
254
|
-
req.method(),
|
|
255
|
-
req.headers(),
|
|
256
|
-
path_params.0,
|
|
257
|
-
without_body_options,
|
|
258
|
-
);
|
|
259
|
-
let mut req = req;
|
|
260
|
-
if handler.wants_request_extensions() {
|
|
261
|
-
req.extensions_mut().insert(Arc::new(request_data.clone()));
|
|
262
|
-
}
|
|
263
|
-
call_with_optional_hooks(req, request_data, handler, hooks).await
|
|
264
|
-
}
|
|
265
|
-
})
|
|
266
|
-
}
|
|
267
|
-
HttpMethod::Delete => {
|
|
268
|
-
let handler_for_closure = handler.clone();
|
|
269
|
-
let hooks_for_closure = hooks.clone();
|
|
270
|
-
axum::routing::delete(move |path_params: Path<HashMap<String, String>>, req: AxumRequest| {
|
|
271
|
-
let handler = handler_for_closure.clone();
|
|
272
|
-
let hooks = hooks_for_closure.clone();
|
|
273
|
-
async move {
|
|
274
|
-
let request_data = request_extraction::create_request_data_without_body(
|
|
275
|
-
req.uri(),
|
|
276
|
-
req.method(),
|
|
277
|
-
req.headers(),
|
|
278
|
-
path_params.0,
|
|
279
|
-
without_body_options,
|
|
280
|
-
);
|
|
281
|
-
let mut req = req;
|
|
282
|
-
if handler.wants_request_extensions() {
|
|
283
|
-
req.extensions_mut().insert(Arc::new(request_data.clone()));
|
|
284
|
-
}
|
|
285
|
-
call_with_optional_hooks(req, request_data, handler, hooks).await
|
|
286
|
-
}
|
|
287
|
-
})
|
|
288
|
-
}
|
|
289
|
-
HttpMethod::Head => {
|
|
290
|
-
let handler_for_closure = handler.clone();
|
|
291
|
-
let hooks_for_closure = hooks.clone();
|
|
292
|
-
axum::routing::head(move |path_params: Path<HashMap<String, String>>, req: AxumRequest| {
|
|
293
|
-
let handler = handler_for_closure.clone();
|
|
294
|
-
let hooks = hooks_for_closure.clone();
|
|
295
|
-
async move {
|
|
296
|
-
let request_data = request_extraction::create_request_data_without_body(
|
|
297
|
-
req.uri(),
|
|
298
|
-
req.method(),
|
|
299
|
-
req.headers(),
|
|
300
|
-
path_params.0,
|
|
301
|
-
without_body_options,
|
|
302
|
-
);
|
|
303
|
-
let mut req = req;
|
|
304
|
-
if handler.wants_request_extensions() {
|
|
305
|
-
req.extensions_mut().insert(Arc::new(request_data.clone()));
|
|
306
|
-
}
|
|
307
|
-
call_with_optional_hooks(req, request_data, handler, hooks).await
|
|
308
|
-
}
|
|
309
|
-
})
|
|
310
|
-
}
|
|
311
|
-
HttpMethod::Trace => {
|
|
312
|
-
let handler_for_closure = handler.clone();
|
|
313
|
-
let hooks_for_closure = hooks.clone();
|
|
314
|
-
axum::routing::trace(move |path_params: Path<HashMap<String, String>>, req: AxumRequest| {
|
|
315
|
-
let handler = handler_for_closure.clone();
|
|
316
|
-
let hooks = hooks_for_closure.clone();
|
|
317
|
-
async move {
|
|
318
|
-
let request_data = request_extraction::create_request_data_without_body(
|
|
319
|
-
req.uri(),
|
|
320
|
-
req.method(),
|
|
321
|
-
req.headers(),
|
|
322
|
-
path_params.0,
|
|
323
|
-
without_body_options,
|
|
324
|
-
);
|
|
325
|
-
let mut req = req;
|
|
326
|
-
if handler.wants_request_extensions() {
|
|
327
|
-
req.extensions_mut().insert(Arc::new(request_data.clone()));
|
|
328
|
-
}
|
|
329
|
-
call_with_optional_hooks(req, request_data, handler, hooks).await
|
|
330
|
-
}
|
|
331
|
-
})
|
|
332
|
-
}
|
|
333
|
-
HttpMethod::Options => {
|
|
334
|
-
let handler_for_closure = handler.clone();
|
|
335
|
-
let hooks_for_closure = hooks.clone();
|
|
336
|
-
axum::routing::options(move |path_params: Path<HashMap<String, String>>, req: AxumRequest| {
|
|
337
|
-
let handler = handler_for_closure.clone();
|
|
338
|
-
let hooks = hooks_for_closure.clone();
|
|
339
|
-
async move {
|
|
340
|
-
let request_data = request_extraction::create_request_data_without_body(
|
|
341
|
-
req.uri(),
|
|
342
|
-
req.method(),
|
|
343
|
-
req.headers(),
|
|
344
|
-
path_params.0,
|
|
345
|
-
without_body_options,
|
|
346
|
-
);
|
|
347
|
-
let mut req = req;
|
|
348
|
-
if handler.wants_request_extensions() {
|
|
349
|
-
req.extensions_mut().insert(Arc::new(request_data.clone()));
|
|
350
|
-
}
|
|
351
|
-
call_with_optional_hooks(req, request_data, handler, hooks).await
|
|
352
|
-
}
|
|
353
|
-
})
|
|
354
|
-
}
|
|
355
|
-
_ => MethodRouter::new(),
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
/// Create a method router for a route without path parameters
|
|
361
|
-
///
|
|
362
|
-
/// Performance: Each match arm only clones the Arc when needed for that specific
|
|
363
|
-
/// HTTP method, avoiding redundant clones at the function level.
|
|
364
|
-
fn create_without_path_params(
|
|
365
|
-
method: HttpMethod,
|
|
366
|
-
handler: Arc<dyn Handler>,
|
|
367
|
-
hooks: Option<Arc<crate::LifecycleHooks>>,
|
|
368
|
-
include_raw_query_params: bool,
|
|
369
|
-
include_query_params_json: bool,
|
|
370
|
-
include_headers: bool,
|
|
371
|
-
include_cookies: bool,
|
|
372
|
-
) -> MethodRouter {
|
|
373
|
-
// Performance: Removed redundant outer clones. Each match arm clones only when needed.
|
|
374
|
-
let without_body_options = request_extraction::WithoutBodyExtractionOptions {
|
|
375
|
-
include_raw_query_params,
|
|
376
|
-
include_query_params_json,
|
|
377
|
-
include_headers,
|
|
378
|
-
include_cookies,
|
|
379
|
-
};
|
|
380
|
-
|
|
381
|
-
if method.expects_body() {
|
|
382
|
-
match method {
|
|
383
|
-
HttpMethod::Post => {
|
|
384
|
-
let handler_for_closure = handler.clone();
|
|
385
|
-
let hooks_for_closure = hooks.clone();
|
|
386
|
-
axum::routing::post(move |req: AxumRequest| {
|
|
387
|
-
let handler = handler_for_closure.clone();
|
|
388
|
-
let hooks = hooks_for_closure.clone();
|
|
389
|
-
async move {
|
|
390
|
-
let (parts, body) = req.into_parts();
|
|
391
|
-
let request_data = request_extraction::create_request_data_with_body(
|
|
392
|
-
&parts,
|
|
393
|
-
HashMap::new(),
|
|
394
|
-
body,
|
|
395
|
-
include_raw_query_params,
|
|
396
|
-
include_query_params_json,
|
|
397
|
-
include_headers,
|
|
398
|
-
include_cookies,
|
|
399
|
-
)
|
|
400
|
-
.await?;
|
|
401
|
-
let mut req = Request::from_parts(
|
|
402
|
-
parts,
|
|
403
|
-
Body::from(request_data.raw_body.clone().unwrap_or_else(Bytes::new)),
|
|
404
|
-
);
|
|
405
|
-
if handler.wants_request_extensions() {
|
|
406
|
-
req.extensions_mut().insert(Arc::new(request_data.clone()));
|
|
407
|
-
}
|
|
408
|
-
call_with_optional_hooks(req, request_data, handler, hooks).await
|
|
409
|
-
}
|
|
410
|
-
})
|
|
411
|
-
}
|
|
412
|
-
HttpMethod::Put => {
|
|
413
|
-
let handler_for_closure = handler.clone();
|
|
414
|
-
let hooks_for_closure = hooks.clone();
|
|
415
|
-
axum::routing::put(move |req: AxumRequest| {
|
|
416
|
-
let handler = handler_for_closure.clone();
|
|
417
|
-
let hooks = hooks_for_closure.clone();
|
|
418
|
-
async move {
|
|
419
|
-
let (parts, body) = req.into_parts();
|
|
420
|
-
let request_data = request_extraction::create_request_data_with_body(
|
|
421
|
-
&parts,
|
|
422
|
-
HashMap::new(),
|
|
423
|
-
body,
|
|
424
|
-
include_raw_query_params,
|
|
425
|
-
include_query_params_json,
|
|
426
|
-
include_headers,
|
|
427
|
-
include_cookies,
|
|
428
|
-
)
|
|
429
|
-
.await?;
|
|
430
|
-
let mut req = Request::from_parts(
|
|
431
|
-
parts,
|
|
432
|
-
Body::from(request_data.raw_body.clone().unwrap_or_else(Bytes::new)),
|
|
433
|
-
);
|
|
434
|
-
if handler.wants_request_extensions() {
|
|
435
|
-
req.extensions_mut().insert(Arc::new(request_data.clone()));
|
|
436
|
-
}
|
|
437
|
-
call_with_optional_hooks(req, request_data, handler, hooks).await
|
|
438
|
-
}
|
|
439
|
-
})
|
|
440
|
-
}
|
|
441
|
-
HttpMethod::Patch => {
|
|
442
|
-
let handler_for_closure = handler.clone();
|
|
443
|
-
let hooks_for_closure = hooks.clone();
|
|
444
|
-
axum::routing::patch(move |req: AxumRequest| {
|
|
445
|
-
let handler = handler_for_closure.clone();
|
|
446
|
-
let hooks = hooks_for_closure.clone();
|
|
447
|
-
async move {
|
|
448
|
-
let (parts, body) = req.into_parts();
|
|
449
|
-
let request_data = request_extraction::create_request_data_with_body(
|
|
450
|
-
&parts,
|
|
451
|
-
HashMap::new(),
|
|
452
|
-
body,
|
|
453
|
-
include_raw_query_params,
|
|
454
|
-
include_query_params_json,
|
|
455
|
-
include_headers,
|
|
456
|
-
include_cookies,
|
|
457
|
-
)
|
|
458
|
-
.await?;
|
|
459
|
-
let mut req = Request::from_parts(
|
|
460
|
-
parts,
|
|
461
|
-
Body::from(request_data.raw_body.clone().unwrap_or_else(Bytes::new)),
|
|
462
|
-
);
|
|
463
|
-
if handler.wants_request_extensions() {
|
|
464
|
-
req.extensions_mut().insert(Arc::new(request_data.clone()));
|
|
465
|
-
}
|
|
466
|
-
call_with_optional_hooks(req, request_data, handler, hooks).await
|
|
467
|
-
}
|
|
468
|
-
})
|
|
469
|
-
}
|
|
470
|
-
_ => MethodRouter::new(),
|
|
471
|
-
}
|
|
472
|
-
} else {
|
|
473
|
-
match method {
|
|
474
|
-
HttpMethod::Get => {
|
|
475
|
-
let handler_for_closure = handler.clone();
|
|
476
|
-
let hooks_for_closure = hooks.clone();
|
|
477
|
-
axum::routing::get(move |req: AxumRequest| {
|
|
478
|
-
let handler = handler_for_closure.clone();
|
|
479
|
-
let hooks = hooks_for_closure.clone();
|
|
480
|
-
async move {
|
|
481
|
-
let request_data = request_extraction::create_request_data_without_body(
|
|
482
|
-
req.uri(),
|
|
483
|
-
req.method(),
|
|
484
|
-
req.headers(),
|
|
485
|
-
HashMap::new(),
|
|
486
|
-
without_body_options,
|
|
487
|
-
);
|
|
488
|
-
let mut req = req;
|
|
489
|
-
if handler.wants_request_extensions() {
|
|
490
|
-
req.extensions_mut().insert(Arc::new(request_data.clone()));
|
|
491
|
-
}
|
|
492
|
-
call_with_optional_hooks(req, request_data, handler, hooks).await
|
|
493
|
-
}
|
|
494
|
-
})
|
|
495
|
-
}
|
|
496
|
-
HttpMethod::Delete => {
|
|
497
|
-
let handler_for_closure = handler.clone();
|
|
498
|
-
let hooks_for_closure = hooks.clone();
|
|
499
|
-
axum::routing::delete(move |req: AxumRequest| {
|
|
500
|
-
let handler = handler_for_closure.clone();
|
|
501
|
-
let hooks = hooks_for_closure.clone();
|
|
502
|
-
async move {
|
|
503
|
-
let request_data = request_extraction::create_request_data_without_body(
|
|
504
|
-
req.uri(),
|
|
505
|
-
req.method(),
|
|
506
|
-
req.headers(),
|
|
507
|
-
HashMap::new(),
|
|
508
|
-
without_body_options,
|
|
509
|
-
);
|
|
510
|
-
let mut req = req;
|
|
511
|
-
if handler.wants_request_extensions() {
|
|
512
|
-
req.extensions_mut().insert(Arc::new(request_data.clone()));
|
|
513
|
-
}
|
|
514
|
-
call_with_optional_hooks(req, request_data, handler, hooks).await
|
|
515
|
-
}
|
|
516
|
-
})
|
|
517
|
-
}
|
|
518
|
-
HttpMethod::Head => {
|
|
519
|
-
let handler_for_closure = handler.clone();
|
|
520
|
-
let hooks_for_closure = hooks.clone();
|
|
521
|
-
axum::routing::head(move |req: AxumRequest| {
|
|
522
|
-
let handler = handler_for_closure.clone();
|
|
523
|
-
let hooks = hooks_for_closure.clone();
|
|
524
|
-
async move {
|
|
525
|
-
let request_data = request_extraction::create_request_data_without_body(
|
|
526
|
-
req.uri(),
|
|
527
|
-
req.method(),
|
|
528
|
-
req.headers(),
|
|
529
|
-
HashMap::new(),
|
|
530
|
-
without_body_options,
|
|
531
|
-
);
|
|
532
|
-
let mut req = req;
|
|
533
|
-
if handler.wants_request_extensions() {
|
|
534
|
-
req.extensions_mut().insert(Arc::new(request_data.clone()));
|
|
535
|
-
}
|
|
536
|
-
call_with_optional_hooks(req, request_data, handler, hooks).await
|
|
537
|
-
}
|
|
538
|
-
})
|
|
539
|
-
}
|
|
540
|
-
HttpMethod::Trace => {
|
|
541
|
-
let handler_for_closure = handler.clone();
|
|
542
|
-
let hooks_for_closure = hooks.clone();
|
|
543
|
-
axum::routing::trace(move |req: AxumRequest| {
|
|
544
|
-
let handler = handler_for_closure.clone();
|
|
545
|
-
let hooks = hooks_for_closure.clone();
|
|
546
|
-
async move {
|
|
547
|
-
let request_data = request_extraction::create_request_data_without_body(
|
|
548
|
-
req.uri(),
|
|
549
|
-
req.method(),
|
|
550
|
-
req.headers(),
|
|
551
|
-
HashMap::new(),
|
|
552
|
-
without_body_options,
|
|
553
|
-
);
|
|
554
|
-
let mut req = req;
|
|
555
|
-
if handler.wants_request_extensions() {
|
|
556
|
-
req.extensions_mut().insert(Arc::new(request_data.clone()));
|
|
557
|
-
}
|
|
558
|
-
call_with_optional_hooks(req, request_data, handler, hooks).await
|
|
559
|
-
}
|
|
560
|
-
})
|
|
561
|
-
}
|
|
562
|
-
HttpMethod::Options => {
|
|
563
|
-
let handler_for_closure = handler.clone();
|
|
564
|
-
let hooks_for_closure = hooks.clone();
|
|
565
|
-
axum::routing::options(move |req: AxumRequest| {
|
|
566
|
-
let handler = handler_for_closure.clone();
|
|
567
|
-
let hooks = hooks_for_closure.clone();
|
|
568
|
-
async move {
|
|
569
|
-
let request_data = request_extraction::create_request_data_without_body(
|
|
570
|
-
req.uri(),
|
|
571
|
-
req.method(),
|
|
572
|
-
req.headers(),
|
|
573
|
-
HashMap::new(),
|
|
574
|
-
without_body_options,
|
|
575
|
-
);
|
|
576
|
-
let mut req = req;
|
|
577
|
-
if handler.wants_request_extensions() {
|
|
578
|
-
req.extensions_mut().insert(Arc::new(request_data.clone()));
|
|
579
|
-
}
|
|
580
|
-
call_with_optional_hooks(req, request_data, handler, hooks).await
|
|
581
|
-
}
|
|
582
|
-
})
|
|
583
|
-
}
|
|
584
|
-
_ => MethodRouter::new(),
|
|
585
|
-
}
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
#[cfg(test)]
|
|
591
|
-
mod tests {
|
|
592
|
-
use super::*;
|
|
593
|
-
|
|
594
|
-
#[test]
|
|
595
|
-
fn test_http_method_from_str() {
|
|
596
|
-
assert_eq!(HttpMethod::from_str("GET"), Some(HttpMethod::Get));
|
|
597
|
-
assert_eq!(HttpMethod::from_str("POST"), Some(HttpMethod::Post));
|
|
598
|
-
assert_eq!(HttpMethod::from_str("PUT"), Some(HttpMethod::Put));
|
|
599
|
-
assert_eq!(HttpMethod::from_str("PATCH"), Some(HttpMethod::Patch));
|
|
600
|
-
assert_eq!(HttpMethod::from_str("DELETE"), Some(HttpMethod::Delete));
|
|
601
|
-
assert_eq!(HttpMethod::from_str("HEAD"), Some(HttpMethod::Head));
|
|
602
|
-
assert_eq!(HttpMethod::from_str("TRACE"), Some(HttpMethod::Trace));
|
|
603
|
-
assert_eq!(HttpMethod::from_str("OPTIONS"), Some(HttpMethod::Options));
|
|
604
|
-
assert_eq!(HttpMethod::from_str("INVALID"), None);
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
#[test]
|
|
608
|
-
fn test_http_method_expects_body() {
|
|
609
|
-
assert!(!HttpMethod::Get.expects_body());
|
|
610
|
-
assert!(HttpMethod::Post.expects_body());
|
|
611
|
-
assert!(HttpMethod::Put.expects_body());
|
|
612
|
-
assert!(HttpMethod::Patch.expects_body());
|
|
613
|
-
assert!(!HttpMethod::Delete.expects_body());
|
|
614
|
-
assert!(!HttpMethod::Head.expects_body());
|
|
615
|
-
assert!(!HttpMethod::Trace.expects_body());
|
|
616
|
-
assert!(!HttpMethod::Options.expects_body());
|
|
617
|
-
}
|
|
618
|
-
}
|