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,194 +1,194 @@
|
|
|
1
|
-
//! Language-agnostic conversion interfaces
|
|
2
|
-
|
|
3
|
-
use std::any::Any;
|
|
4
|
-
|
|
5
|
-
/// Trait for converting from language-specific types to Rust types
|
|
6
|
-
pub trait FromLanguage: Sized {
|
|
7
|
-
/// The error type for conversion failures
|
|
8
|
-
type Error: std::fmt::Display;
|
|
9
|
-
|
|
10
|
-
/// Convert from a language-specific value
|
|
11
|
-
fn from_any(value: &(dyn Any + Send + Sync)) -> Result<Self, Self::Error>;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/// Trait for converting from Rust types to language-specific types
|
|
15
|
-
pub trait ToLanguage {
|
|
16
|
-
/// The error type for conversion failures
|
|
17
|
-
type Error: std::fmt::Display;
|
|
18
|
-
|
|
19
|
-
/// Convert to a language-specific value
|
|
20
|
-
fn to_any(&self) -> Result<Box<dyn Any + Send + Sync>, Self::Error>;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/// Trait for converting to/from JSON values
|
|
24
|
-
pub trait JsonConvertible: Sized {
|
|
25
|
-
/// The error type for conversion failures
|
|
26
|
-
type Error: std::fmt::Display;
|
|
27
|
-
|
|
28
|
-
/// Convert from a JSON value
|
|
29
|
-
fn from_json(value: serde_json::Value) -> Result<Self, Self::Error>;
|
|
30
|
-
|
|
31
|
-
/// Convert to a JSON value
|
|
32
|
-
fn to_json(&self) -> Result<serde_json::Value, Self::Error>;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/// Default JSON conversion error
|
|
36
|
-
#[derive(Debug)]
|
|
37
|
-
pub struct JsonConversionError(pub String);
|
|
38
|
-
|
|
39
|
-
impl std::fmt::Display for JsonConversionError {
|
|
40
|
-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
41
|
-
write!(f, "JSON conversion error: {}", self.0)
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/// Default implementation for JSON values
|
|
46
|
-
impl JsonConvertible for serde_json::Value {
|
|
47
|
-
type Error = JsonConversionError;
|
|
48
|
-
|
|
49
|
-
fn from_json(value: serde_json::Value) -> Result<Self, Self::Error> {
|
|
50
|
-
Ok(value)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
fn to_json(&self) -> Result<serde_json::Value, Self::Error> {
|
|
54
|
-
Ok(self.clone())
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
#[cfg(test)]
|
|
59
|
-
mod tests {
|
|
60
|
-
use super::*;
|
|
61
|
-
use serde_json::json;
|
|
62
|
-
|
|
63
|
-
#[derive(Debug)]
|
|
64
|
-
struct TestType {
|
|
65
|
-
value: i32,
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
impl FromLanguage for TestType {
|
|
69
|
-
type Error = String;
|
|
70
|
-
|
|
71
|
-
fn from_any(value: &(dyn Any + Send + Sync)) -> Result<Self, Self::Error> {
|
|
72
|
-
value
|
|
73
|
-
.downcast_ref::<i32>()
|
|
74
|
-
.map(|&v| TestType { value: v })
|
|
75
|
-
.ok_or_else(|| "Invalid type".to_string())
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
impl ToLanguage for TestType {
|
|
80
|
-
type Error = String;
|
|
81
|
-
|
|
82
|
-
fn to_any(&self) -> Result<Box<dyn Any + Send + Sync>, Self::Error> {
|
|
83
|
-
Ok(Box::new(self.value))
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
#[test]
|
|
88
|
-
fn test_json_conversion_error_display() {
|
|
89
|
-
let err = JsonConversionError("test error".to_string());
|
|
90
|
-
assert_eq!(err.to_string(), "JSON conversion error: test error");
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
#[test]
|
|
94
|
-
fn test_json_value_from_json() {
|
|
95
|
-
let input = json!({ "key": "value" });
|
|
96
|
-
let result = serde_json::Value::from_json(input.clone());
|
|
97
|
-
assert!(result.is_ok());
|
|
98
|
-
assert_eq!(result.unwrap(), input);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
#[test]
|
|
102
|
-
fn test_json_value_to_json() {
|
|
103
|
-
let input = json!({ "key": "value" });
|
|
104
|
-
let result = serde_json::Value::to_json(&input);
|
|
105
|
-
assert!(result.is_ok());
|
|
106
|
-
assert_eq!(result.unwrap(), input);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
#[test]
|
|
110
|
-
fn test_json_value_roundtrip() {
|
|
111
|
-
let original = json!({
|
|
112
|
-
"string": "test",
|
|
113
|
-
"number": 42,
|
|
114
|
-
"float": 3.2,
|
|
115
|
-
"bool": true,
|
|
116
|
-
"null": null,
|
|
117
|
-
"array": [1, 2, 3],
|
|
118
|
-
"object": { "nested": "value" }
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
let converted = serde_json::Value::from_json(original.clone()).unwrap();
|
|
122
|
-
let back = converted.to_json().unwrap();
|
|
123
|
-
assert_eq!(original, back);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
#[test]
|
|
127
|
-
fn test_from_language_trait() {
|
|
128
|
-
let any_value: Box<dyn Any + Send + Sync> = Box::new(42i32);
|
|
129
|
-
let result = TestType::from_any(&*any_value);
|
|
130
|
-
assert!(result.is_ok());
|
|
131
|
-
assert_eq!(result.unwrap().value, 42);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
#[test]
|
|
135
|
-
fn test_from_language_wrong_type() {
|
|
136
|
-
let any_value: Box<dyn Any + Send + Sync> = Box::new("string");
|
|
137
|
-
let result = TestType::from_any(&*any_value);
|
|
138
|
-
assert!(result.is_err());
|
|
139
|
-
assert_eq!(result.unwrap_err(), "Invalid type");
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
#[test]
|
|
143
|
-
fn test_to_language_trait() {
|
|
144
|
-
let test_obj = TestType { value: 123 };
|
|
145
|
-
let result = test_obj.to_any();
|
|
146
|
-
assert!(result.is_ok());
|
|
147
|
-
|
|
148
|
-
let any_box = result.unwrap();
|
|
149
|
-
let downcast = any_box.downcast_ref::<i32>();
|
|
150
|
-
assert_eq!(*downcast.unwrap(), 123);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
#[test]
|
|
154
|
-
fn test_json_null_conversion() {
|
|
155
|
-
let null_value = serde_json::Value::Null;
|
|
156
|
-
let result = serde_json::Value::from_json(null_value.clone());
|
|
157
|
-
assert!(result.is_ok());
|
|
158
|
-
assert!(result.unwrap().is_null());
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
#[test]
|
|
162
|
-
fn test_json_array_conversion() {
|
|
163
|
-
let array = json!([1, 2, 3, 4, 5]);
|
|
164
|
-
let result = serde_json::Value::from_json(array.clone());
|
|
165
|
-
assert!(result.is_ok());
|
|
166
|
-
let converted = result.unwrap();
|
|
167
|
-
assert!(converted.is_array());
|
|
168
|
-
assert_eq!(converted.as_array().unwrap().len(), 5);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
#[test]
|
|
172
|
-
fn test_json_nested_object_conversion() {
|
|
173
|
-
let nested = json!({
|
|
174
|
-
"level1": {
|
|
175
|
-
"level2": {
|
|
176
|
-
"level3": {
|
|
177
|
-
"value": "deep"
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
let result = serde_json::Value::from_json(nested.clone());
|
|
184
|
-
assert!(result.is_ok());
|
|
185
|
-
let converted = result.unwrap();
|
|
186
|
-
assert_eq!(converted["level1"]["level2"]["level3"]["value"], "deep");
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
#[test]
|
|
190
|
-
fn test_json_conversion_error_description() {
|
|
191
|
-
let err = JsonConversionError("Custom message".to_string());
|
|
192
|
-
assert!(err.to_string().contains("Custom message"));
|
|
193
|
-
}
|
|
194
|
-
}
|
|
1
|
+
//! Language-agnostic conversion interfaces
|
|
2
|
+
|
|
3
|
+
use std::any::Any;
|
|
4
|
+
|
|
5
|
+
/// Trait for converting from language-specific types to Rust types
|
|
6
|
+
pub trait FromLanguage: Sized {
|
|
7
|
+
/// The error type for conversion failures
|
|
8
|
+
type Error: std::fmt::Display;
|
|
9
|
+
|
|
10
|
+
/// Convert from a language-specific value
|
|
11
|
+
fn from_any(value: &(dyn Any + Send + Sync)) -> Result<Self, Self::Error>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/// Trait for converting from Rust types to language-specific types
|
|
15
|
+
pub trait ToLanguage {
|
|
16
|
+
/// The error type for conversion failures
|
|
17
|
+
type Error: std::fmt::Display;
|
|
18
|
+
|
|
19
|
+
/// Convert to a language-specific value
|
|
20
|
+
fn to_any(&self) -> Result<Box<dyn Any + Send + Sync>, Self::Error>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/// Trait for converting to/from JSON values
|
|
24
|
+
pub trait JsonConvertible: Sized {
|
|
25
|
+
/// The error type for conversion failures
|
|
26
|
+
type Error: std::fmt::Display;
|
|
27
|
+
|
|
28
|
+
/// Convert from a JSON value
|
|
29
|
+
fn from_json(value: serde_json::Value) -> Result<Self, Self::Error>;
|
|
30
|
+
|
|
31
|
+
/// Convert to a JSON value
|
|
32
|
+
fn to_json(&self) -> Result<serde_json::Value, Self::Error>;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/// Default JSON conversion error
|
|
36
|
+
#[derive(Debug)]
|
|
37
|
+
pub struct JsonConversionError(pub String);
|
|
38
|
+
|
|
39
|
+
impl std::fmt::Display for JsonConversionError {
|
|
40
|
+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
41
|
+
write!(f, "JSON conversion error: {}", self.0)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/// Default implementation for JSON values
|
|
46
|
+
impl JsonConvertible for serde_json::Value {
|
|
47
|
+
type Error = JsonConversionError;
|
|
48
|
+
|
|
49
|
+
fn from_json(value: serde_json::Value) -> Result<Self, Self::Error> {
|
|
50
|
+
Ok(value)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
fn to_json(&self) -> Result<serde_json::Value, Self::Error> {
|
|
54
|
+
Ok(self.clone())
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
#[cfg(test)]
|
|
59
|
+
mod tests {
|
|
60
|
+
use super::*;
|
|
61
|
+
use serde_json::json;
|
|
62
|
+
|
|
63
|
+
#[derive(Debug)]
|
|
64
|
+
struct TestType {
|
|
65
|
+
value: i32,
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
impl FromLanguage for TestType {
|
|
69
|
+
type Error = String;
|
|
70
|
+
|
|
71
|
+
fn from_any(value: &(dyn Any + Send + Sync)) -> Result<Self, Self::Error> {
|
|
72
|
+
value
|
|
73
|
+
.downcast_ref::<i32>()
|
|
74
|
+
.map(|&v| TestType { value: v })
|
|
75
|
+
.ok_or_else(|| "Invalid type".to_string())
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
impl ToLanguage for TestType {
|
|
80
|
+
type Error = String;
|
|
81
|
+
|
|
82
|
+
fn to_any(&self) -> Result<Box<dyn Any + Send + Sync>, Self::Error> {
|
|
83
|
+
Ok(Box::new(self.value))
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
#[test]
|
|
88
|
+
fn test_json_conversion_error_display() {
|
|
89
|
+
let err = JsonConversionError("test error".to_string());
|
|
90
|
+
assert_eq!(err.to_string(), "JSON conversion error: test error");
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
#[test]
|
|
94
|
+
fn test_json_value_from_json() {
|
|
95
|
+
let input = json!({ "key": "value" });
|
|
96
|
+
let result = serde_json::Value::from_json(input.clone());
|
|
97
|
+
assert!(result.is_ok());
|
|
98
|
+
assert_eq!(result.unwrap(), input);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
#[test]
|
|
102
|
+
fn test_json_value_to_json() {
|
|
103
|
+
let input = json!({ "key": "value" });
|
|
104
|
+
let result = serde_json::Value::to_json(&input);
|
|
105
|
+
assert!(result.is_ok());
|
|
106
|
+
assert_eq!(result.unwrap(), input);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
#[test]
|
|
110
|
+
fn test_json_value_roundtrip() {
|
|
111
|
+
let original = json!({
|
|
112
|
+
"string": "test",
|
|
113
|
+
"number": 42,
|
|
114
|
+
"float": 3.2,
|
|
115
|
+
"bool": true,
|
|
116
|
+
"null": null,
|
|
117
|
+
"array": [1, 2, 3],
|
|
118
|
+
"object": { "nested": "value" }
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
let converted = serde_json::Value::from_json(original.clone()).unwrap();
|
|
122
|
+
let back = converted.to_json().unwrap();
|
|
123
|
+
assert_eq!(original, back);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
#[test]
|
|
127
|
+
fn test_from_language_trait() {
|
|
128
|
+
let any_value: Box<dyn Any + Send + Sync> = Box::new(42i32);
|
|
129
|
+
let result = TestType::from_any(&*any_value);
|
|
130
|
+
assert!(result.is_ok());
|
|
131
|
+
assert_eq!(result.unwrap().value, 42);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
#[test]
|
|
135
|
+
fn test_from_language_wrong_type() {
|
|
136
|
+
let any_value: Box<dyn Any + Send + Sync> = Box::new("string");
|
|
137
|
+
let result = TestType::from_any(&*any_value);
|
|
138
|
+
assert!(result.is_err());
|
|
139
|
+
assert_eq!(result.unwrap_err(), "Invalid type");
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
#[test]
|
|
143
|
+
fn test_to_language_trait() {
|
|
144
|
+
let test_obj = TestType { value: 123 };
|
|
145
|
+
let result = test_obj.to_any();
|
|
146
|
+
assert!(result.is_ok());
|
|
147
|
+
|
|
148
|
+
let any_box = result.unwrap();
|
|
149
|
+
let downcast = any_box.downcast_ref::<i32>();
|
|
150
|
+
assert_eq!(*downcast.unwrap(), 123);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
#[test]
|
|
154
|
+
fn test_json_null_conversion() {
|
|
155
|
+
let null_value = serde_json::Value::Null;
|
|
156
|
+
let result = serde_json::Value::from_json(null_value.clone());
|
|
157
|
+
assert!(result.is_ok());
|
|
158
|
+
assert!(result.unwrap().is_null());
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
#[test]
|
|
162
|
+
fn test_json_array_conversion() {
|
|
163
|
+
let array = json!([1, 2, 3, 4, 5]);
|
|
164
|
+
let result = serde_json::Value::from_json(array.clone());
|
|
165
|
+
assert!(result.is_ok());
|
|
166
|
+
let converted = result.unwrap();
|
|
167
|
+
assert!(converted.is_array());
|
|
168
|
+
assert_eq!(converted.as_array().unwrap().len(), 5);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
#[test]
|
|
172
|
+
fn test_json_nested_object_conversion() {
|
|
173
|
+
let nested = json!({
|
|
174
|
+
"level1": {
|
|
175
|
+
"level2": {
|
|
176
|
+
"level3": {
|
|
177
|
+
"value": "deep"
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
let result = serde_json::Value::from_json(nested.clone());
|
|
184
|
+
assert!(result.is_ok());
|
|
185
|
+
let converted = result.unwrap();
|
|
186
|
+
assert_eq!(converted["level1"]["level2"]["level3"]["value"], "deep");
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
#[test]
|
|
190
|
+
fn test_json_conversion_error_description() {
|
|
191
|
+
let err = JsonConversionError("Custom message".to_string());
|
|
192
|
+
assert!(err.to_string().contains("Custom message"));
|
|
193
|
+
}
|
|
194
|
+
}
|