spikard 0.5.0 → 0.6.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/LICENSE +1 -1
- data/README.md +674 -674
- data/ext/spikard_rb/Cargo.toml +17 -17
- data/ext/spikard_rb/extconf.rb +13 -10
- data/ext/spikard_rb/src/lib.rs +6 -6
- data/lib/spikard/app.rb +405 -405
- data/lib/spikard/background.rb +27 -27
- data/lib/spikard/config.rb +396 -396
- data/lib/spikard/converters.rb +13 -13
- data/lib/spikard/handler_wrapper.rb +113 -113
- data/lib/spikard/provide.rb +214 -214
- data/lib/spikard/response.rb +173 -173
- data/lib/spikard/schema.rb +243 -243
- data/lib/spikard/sse.rb +111 -111
- data/lib/spikard/streaming_response.rb +44 -44
- data/lib/spikard/testing.rb +256 -256
- data/lib/spikard/upload_file.rb +131 -131
- data/lib/spikard/version.rb +5 -5
- data/lib/spikard/websocket.rb +59 -59
- data/lib/spikard.rb +43 -43
- data/sig/spikard.rbs +366 -366
- data/vendor/crates/spikard-bindings-shared/Cargo.toml +63 -63
- data/vendor/crates/spikard-bindings-shared/examples/config_extraction.rs +132 -132
- data/vendor/crates/spikard-bindings-shared/src/config_extractor.rs +752 -752
- data/vendor/crates/spikard-bindings-shared/src/conversion_traits.rs +194 -194
- data/vendor/crates/spikard-bindings-shared/src/di_traits.rs +246 -246
- data/vendor/crates/spikard-bindings-shared/src/error_response.rs +401 -401
- data/vendor/crates/spikard-bindings-shared/src/handler_base.rs +238 -238
- data/vendor/crates/spikard-bindings-shared/src/lib.rs +24 -24
- data/vendor/crates/spikard-bindings-shared/src/lifecycle_base.rs +292 -292
- data/vendor/crates/spikard-bindings-shared/src/lifecycle_executor.rs +616 -616
- data/vendor/crates/spikard-bindings-shared/src/response_builder.rs +305 -305
- data/vendor/crates/spikard-bindings-shared/src/test_client_base.rs +248 -248
- data/vendor/crates/spikard-bindings-shared/src/validation_helpers.rs +351 -351
- data/vendor/crates/spikard-bindings-shared/tests/comprehensive_coverage.rs +454 -454
- data/vendor/crates/spikard-bindings-shared/tests/error_response_edge_cases.rs +383 -383
- data/vendor/crates/spikard-bindings-shared/tests/handler_base_integration.rs +280 -280
- data/vendor/crates/spikard-core/Cargo.toml +40 -40
- data/vendor/crates/spikard-core/src/bindings/mod.rs +3 -3
- data/vendor/crates/spikard-core/src/bindings/response.rs +133 -133
- data/vendor/crates/spikard-core/src/debug.rs +127 -127
- data/vendor/crates/spikard-core/src/di/container.rs +702 -702
- data/vendor/crates/spikard-core/src/di/dependency.rs +273 -273
- data/vendor/crates/spikard-core/src/di/error.rs +118 -118
- data/vendor/crates/spikard-core/src/di/factory.rs +534 -534
- data/vendor/crates/spikard-core/src/di/graph.rs +506 -506
- data/vendor/crates/spikard-core/src/di/mod.rs +192 -192
- data/vendor/crates/spikard-core/src/di/resolved.rs +405 -405
- data/vendor/crates/spikard-core/src/di/value.rs +281 -281
- data/vendor/crates/spikard-core/src/errors.rs +69 -69
- data/vendor/crates/spikard-core/src/http.rs +415 -415
- data/vendor/crates/spikard-core/src/lib.rs +29 -29
- data/vendor/crates/spikard-core/src/lifecycle.rs +1186 -1186
- data/vendor/crates/spikard-core/src/metadata.rs +389 -389
- data/vendor/crates/spikard-core/src/parameters.rs +2525 -2525
- data/vendor/crates/spikard-core/src/problem.rs +344 -344
- data/vendor/crates/spikard-core/src/request_data.rs +1154 -1154
- data/vendor/crates/spikard-core/src/router.rs +510 -510
- data/vendor/crates/spikard-core/src/schema_registry.rs +183 -183
- data/vendor/crates/spikard-core/src/type_hints.rs +304 -304
- data/vendor/crates/spikard-core/src/validation/error_mapper.rs +696 -688
- data/vendor/crates/spikard-core/src/validation/mod.rs +457 -457
- data/vendor/crates/spikard-http/Cargo.toml +62 -64
- data/vendor/crates/spikard-http/examples/sse-notifications.rs +148 -148
- data/vendor/crates/spikard-http/examples/websocket-chat.rs +92 -92
- data/vendor/crates/spikard-http/src/auth.rs +296 -296
- data/vendor/crates/spikard-http/src/background.rs +1860 -1860
- data/vendor/crates/spikard-http/src/bindings/mod.rs +3 -3
- data/vendor/crates/spikard-http/src/bindings/response.rs +1 -1
- data/vendor/crates/spikard-http/src/body_metadata.rs +8 -8
- data/vendor/crates/spikard-http/src/cors.rs +1005 -1005
- data/vendor/crates/spikard-http/src/debug.rs +128 -128
- data/vendor/crates/spikard-http/src/di_handler.rs +1668 -1668
- data/vendor/crates/spikard-http/src/handler_response.rs +901 -901
- data/vendor/crates/spikard-http/src/handler_trait.rs +838 -830
- data/vendor/crates/spikard-http/src/handler_trait_tests.rs +290 -290
- data/vendor/crates/spikard-http/src/lib.rs +534 -534
- data/vendor/crates/spikard-http/src/lifecycle/adapter.rs +230 -230
- data/vendor/crates/spikard-http/src/lifecycle.rs +1193 -1193
- data/vendor/crates/spikard-http/src/middleware/mod.rs +560 -540
- data/vendor/crates/spikard-http/src/middleware/multipart.rs +912 -912
- data/vendor/crates/spikard-http/src/middleware/urlencoded.rs +513 -513
- data/vendor/crates/spikard-http/src/middleware/validation.rs +768 -735
- data/vendor/crates/spikard-http/src/openapi/mod.rs +309 -309
- data/vendor/crates/spikard-http/src/openapi/parameter_extraction.rs +535 -535
- data/vendor/crates/spikard-http/src/openapi/schema_conversion.rs +1363 -1363
- data/vendor/crates/spikard-http/src/openapi/spec_generation.rs +665 -665
- data/vendor/crates/spikard-http/src/query_parser.rs +793 -793
- data/vendor/crates/spikard-http/src/response.rs +720 -720
- data/vendor/crates/spikard-http/src/server/handler.rs +1650 -1650
- data/vendor/crates/spikard-http/src/server/lifecycle_execution.rs +234 -234
- data/vendor/crates/spikard-http/src/server/mod.rs +1593 -1502
- data/vendor/crates/spikard-http/src/server/request_extraction.rs +789 -770
- data/vendor/crates/spikard-http/src/server/routing_factory.rs +629 -599
- data/vendor/crates/spikard-http/src/sse.rs +1409 -1409
- data/vendor/crates/spikard-http/src/testing/form.rs +52 -52
- data/vendor/crates/spikard-http/src/testing/multipart.rs +64 -60
- data/vendor/crates/spikard-http/src/testing/test_client.rs +311 -283
- data/vendor/crates/spikard-http/src/testing.rs +406 -377
- data/vendor/crates/spikard-http/src/websocket.rs +1404 -1375
- data/vendor/crates/spikard-http/tests/background_behavior.rs +832 -832
- data/vendor/crates/spikard-http/tests/common/handlers.rs +309 -309
- data/vendor/crates/spikard-http/tests/common/mod.rs +26 -26
- data/vendor/crates/spikard-http/tests/di_integration.rs +192 -192
- data/vendor/crates/spikard-http/tests/doc_snippets.rs +5 -5
- data/vendor/crates/spikard-http/tests/lifecycle_execution.rs +1093 -1093
- data/vendor/crates/spikard-http/tests/multipart_behavior.rs +656 -656
- data/vendor/crates/spikard-http/tests/server_config_builder.rs +314 -314
- data/vendor/crates/spikard-http/tests/sse_behavior.rs +620 -620
- data/vendor/crates/spikard-http/tests/websocket_behavior.rs +663 -663
- data/vendor/crates/spikard-rb/Cargo.toml +48 -48
- data/vendor/crates/spikard-rb/build.rs +199 -199
- data/vendor/crates/spikard-rb/src/background.rs +63 -63
- data/vendor/crates/spikard-rb/src/config/mod.rs +5 -5
- data/vendor/crates/spikard-rb/src/config/server_config.rs +285 -285
- data/vendor/crates/spikard-rb/src/conversion.rs +554 -554
- data/vendor/crates/spikard-rb/src/di/builder.rs +100 -100
- data/vendor/crates/spikard-rb/src/di/mod.rs +375 -375
- data/vendor/crates/spikard-rb/src/handler.rs +618 -618
- data/vendor/crates/spikard-rb/src/integration/mod.rs +3 -3
- data/vendor/crates/spikard-rb/src/lib.rs +1806 -1810
- data/vendor/crates/spikard-rb/src/lifecycle.rs +275 -275
- data/vendor/crates/spikard-rb/src/metadata/mod.rs +5 -5
- data/vendor/crates/spikard-rb/src/metadata/route_extraction.rs +442 -447
- data/vendor/crates/spikard-rb/src/runtime/mod.rs +5 -5
- data/vendor/crates/spikard-rb/src/runtime/server_runner.rs +324 -324
- data/vendor/crates/spikard-rb/src/server.rs +305 -308
- data/vendor/crates/spikard-rb/src/sse.rs +231 -231
- data/vendor/crates/spikard-rb/src/testing/client.rs +538 -551
- data/vendor/crates/spikard-rb/src/testing/mod.rs +7 -7
- data/vendor/crates/spikard-rb/src/testing/sse.rs +143 -143
- data/vendor/crates/spikard-rb/src/testing/websocket.rs +608 -635
- data/vendor/crates/spikard-rb/src/websocket.rs +377 -374
- metadata +15 -1
|
@@ -1,100 +1,100 @@
|
|
|
1
|
-
//! Dependency injection container building from Ruby objects.
|
|
2
|
-
//!
|
|
3
|
-
//! This module handles constructing DependencyContainer instances from Ruby
|
|
4
|
-
//! hashes and factories.
|
|
5
|
-
|
|
6
|
-
use magnus::prelude::*;
|
|
7
|
-
use magnus::{Error, RHash, Ruby, TryConvert, Value, r_hash::ForEach};
|
|
8
|
-
use spikard_core::di::DependencyContainer;
|
|
9
|
-
use std::sync::Arc;
|
|
10
|
-
|
|
11
|
-
/// Build a DependencyContainer from Ruby dependency definitions
|
|
12
|
-
pub fn build_dependency_container(ruby: &Ruby, dependencies: Value) -> Result<DependencyContainer, Error> {
|
|
13
|
-
if dependencies.is_nil() {
|
|
14
|
-
return Ok(DependencyContainer::new());
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
let mut container = DependencyContainer::new();
|
|
18
|
-
let deps_hash = RHash::try_convert(dependencies)?;
|
|
19
|
-
|
|
20
|
-
deps_hash.foreach(|key: String, value: Value| -> Result<ForEach, Error> {
|
|
21
|
-
if let Ok(dep_hash) = RHash::try_convert(value) {
|
|
22
|
-
let dep_type: Option<String> = get_kw(ruby, dep_hash, "type").and_then(|v| {
|
|
23
|
-
if let Ok(sym) = magnus::Symbol::try_convert(v) {
|
|
24
|
-
Some(sym.name().ok()?.to_string())
|
|
25
|
-
} else {
|
|
26
|
-
String::try_convert(v).ok()
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
match dep_type.as_deref() {
|
|
31
|
-
Some("factory") => {
|
|
32
|
-
let factory = get_kw(ruby, dep_hash, "factory")
|
|
33
|
-
.ok_or_else(|| Error::new(ruby.exception_runtime_error(), "Factory missing 'factory' key"))?;
|
|
34
|
-
|
|
35
|
-
let depends_on: Vec<String> = get_kw(ruby, dep_hash, "depends_on")
|
|
36
|
-
.and_then(|v| Vec::<String>::try_convert(v).ok())
|
|
37
|
-
.unwrap_or_default();
|
|
38
|
-
|
|
39
|
-
let singleton: bool = get_kw(ruby, dep_hash, "singleton")
|
|
40
|
-
.and_then(|v| bool::try_convert(v).ok())
|
|
41
|
-
.unwrap_or(false);
|
|
42
|
-
|
|
43
|
-
let cacheable: bool = get_kw(ruby, dep_hash, "cacheable")
|
|
44
|
-
.and_then(|v| bool::try_convert(v).ok())
|
|
45
|
-
.unwrap_or(true);
|
|
46
|
-
|
|
47
|
-
let factory_dep =
|
|
48
|
-
crate::di::RubyFactoryDependency::new(key.clone(), factory, depends_on, singleton, cacheable);
|
|
49
|
-
|
|
50
|
-
container.register(key.clone(), Arc::new(factory_dep)).map_err(|e| {
|
|
51
|
-
Error::new(
|
|
52
|
-
ruby.exception_runtime_error(),
|
|
53
|
-
format!("Failed to register factory '{}': {}", key, e),
|
|
54
|
-
)
|
|
55
|
-
})?;
|
|
56
|
-
}
|
|
57
|
-
Some("value") => {
|
|
58
|
-
let value_data = get_kw(ruby, dep_hash, "value").ok_or_else(|| {
|
|
59
|
-
Error::new(ruby.exception_runtime_error(), "Value dependency missing 'value' key")
|
|
60
|
-
})?;
|
|
61
|
-
|
|
62
|
-
let value_dep = crate::di::RubyValueDependency::new(key.clone(), value_data);
|
|
63
|
-
|
|
64
|
-
container.register(key.clone(), Arc::new(value_dep)).map_err(|e| {
|
|
65
|
-
Error::new(
|
|
66
|
-
ruby.exception_runtime_error(),
|
|
67
|
-
format!("Failed to register value '{}': {}", key, e),
|
|
68
|
-
)
|
|
69
|
-
})?;
|
|
70
|
-
}
|
|
71
|
-
_ => {
|
|
72
|
-
return Err(Error::new(
|
|
73
|
-
ruby.exception_runtime_error(),
|
|
74
|
-
format!("Invalid dependency type for '{}'", key),
|
|
75
|
-
));
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
} else {
|
|
79
|
-
let value_dep = crate::di::RubyValueDependency::new(key.clone(), value);
|
|
80
|
-
container.register(key.clone(), Arc::new(value_dep)).map_err(|e| {
|
|
81
|
-
Error::new(
|
|
82
|
-
ruby.exception_runtime_error(),
|
|
83
|
-
format!("Failed to register value '{}': {}", key, e),
|
|
84
|
-
)
|
|
85
|
-
})?;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
Ok(ForEach::Continue)
|
|
89
|
-
})?;
|
|
90
|
-
|
|
91
|
-
Ok(container)
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/// Get a keyword argument from a Ruby hash (returns None if not present or nil)
|
|
95
|
-
fn get_kw(ruby: &Ruby, hash: RHash, name: &str) -> Option<Value> {
|
|
96
|
-
match hash.get(ruby.to_symbol(name)) {
|
|
97
|
-
Some(v) if !v.is_nil() => Some(v),
|
|
98
|
-
_ => None,
|
|
99
|
-
}
|
|
100
|
-
}
|
|
1
|
+
//! Dependency injection container building from Ruby objects.
|
|
2
|
+
//!
|
|
3
|
+
//! This module handles constructing DependencyContainer instances from Ruby
|
|
4
|
+
//! hashes and factories.
|
|
5
|
+
|
|
6
|
+
use magnus::prelude::*;
|
|
7
|
+
use magnus::{Error, RHash, Ruby, TryConvert, Value, r_hash::ForEach};
|
|
8
|
+
use spikard_core::di::DependencyContainer;
|
|
9
|
+
use std::sync::Arc;
|
|
10
|
+
|
|
11
|
+
/// Build a DependencyContainer from Ruby dependency definitions
|
|
12
|
+
pub fn build_dependency_container(ruby: &Ruby, dependencies: Value) -> Result<DependencyContainer, Error> {
|
|
13
|
+
if dependencies.is_nil() {
|
|
14
|
+
return Ok(DependencyContainer::new());
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let mut container = DependencyContainer::new();
|
|
18
|
+
let deps_hash = RHash::try_convert(dependencies)?;
|
|
19
|
+
|
|
20
|
+
deps_hash.foreach(|key: String, value: Value| -> Result<ForEach, Error> {
|
|
21
|
+
if let Ok(dep_hash) = RHash::try_convert(value) {
|
|
22
|
+
let dep_type: Option<String> = get_kw(ruby, dep_hash, "type").and_then(|v| {
|
|
23
|
+
if let Ok(sym) = magnus::Symbol::try_convert(v) {
|
|
24
|
+
Some(sym.name().ok()?.to_string())
|
|
25
|
+
} else {
|
|
26
|
+
String::try_convert(v).ok()
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
match dep_type.as_deref() {
|
|
31
|
+
Some("factory") => {
|
|
32
|
+
let factory = get_kw(ruby, dep_hash, "factory")
|
|
33
|
+
.ok_or_else(|| Error::new(ruby.exception_runtime_error(), "Factory missing 'factory' key"))?;
|
|
34
|
+
|
|
35
|
+
let depends_on: Vec<String> = get_kw(ruby, dep_hash, "depends_on")
|
|
36
|
+
.and_then(|v| Vec::<String>::try_convert(v).ok())
|
|
37
|
+
.unwrap_or_default();
|
|
38
|
+
|
|
39
|
+
let singleton: bool = get_kw(ruby, dep_hash, "singleton")
|
|
40
|
+
.and_then(|v| bool::try_convert(v).ok())
|
|
41
|
+
.unwrap_or(false);
|
|
42
|
+
|
|
43
|
+
let cacheable: bool = get_kw(ruby, dep_hash, "cacheable")
|
|
44
|
+
.and_then(|v| bool::try_convert(v).ok())
|
|
45
|
+
.unwrap_or(true);
|
|
46
|
+
|
|
47
|
+
let factory_dep =
|
|
48
|
+
crate::di::RubyFactoryDependency::new(key.clone(), factory, depends_on, singleton, cacheable);
|
|
49
|
+
|
|
50
|
+
container.register(key.clone(), Arc::new(factory_dep)).map_err(|e| {
|
|
51
|
+
Error::new(
|
|
52
|
+
ruby.exception_runtime_error(),
|
|
53
|
+
format!("Failed to register factory '{}': {}", key, e),
|
|
54
|
+
)
|
|
55
|
+
})?;
|
|
56
|
+
}
|
|
57
|
+
Some("value") => {
|
|
58
|
+
let value_data = get_kw(ruby, dep_hash, "value").ok_or_else(|| {
|
|
59
|
+
Error::new(ruby.exception_runtime_error(), "Value dependency missing 'value' key")
|
|
60
|
+
})?;
|
|
61
|
+
|
|
62
|
+
let value_dep = crate::di::RubyValueDependency::new(key.clone(), value_data);
|
|
63
|
+
|
|
64
|
+
container.register(key.clone(), Arc::new(value_dep)).map_err(|e| {
|
|
65
|
+
Error::new(
|
|
66
|
+
ruby.exception_runtime_error(),
|
|
67
|
+
format!("Failed to register value '{}': {}", key, e),
|
|
68
|
+
)
|
|
69
|
+
})?;
|
|
70
|
+
}
|
|
71
|
+
_ => {
|
|
72
|
+
return Err(Error::new(
|
|
73
|
+
ruby.exception_runtime_error(),
|
|
74
|
+
format!("Invalid dependency type for '{}'", key),
|
|
75
|
+
));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
} else {
|
|
79
|
+
let value_dep = crate::di::RubyValueDependency::new(key.clone(), value);
|
|
80
|
+
container.register(key.clone(), Arc::new(value_dep)).map_err(|e| {
|
|
81
|
+
Error::new(
|
|
82
|
+
ruby.exception_runtime_error(),
|
|
83
|
+
format!("Failed to register value '{}': {}", key, e),
|
|
84
|
+
)
|
|
85
|
+
})?;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
Ok(ForEach::Continue)
|
|
89
|
+
})?;
|
|
90
|
+
|
|
91
|
+
Ok(container)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/// Get a keyword argument from a Ruby hash (returns None if not present or nil)
|
|
95
|
+
fn get_kw(ruby: &Ruby, hash: RHash, name: &str) -> Option<Value> {
|
|
96
|
+
match hash.get(ruby.to_symbol(name)) {
|
|
97
|
+
Some(v) if !v.is_nil() => Some(v),
|
|
98
|
+
_ => None,
|
|
99
|
+
}
|
|
100
|
+
}
|