spikard 0.2.5 → 0.3.0

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.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +34 -1
  3. data/ext/spikard_rb/Cargo.toml +3 -3
  4. data/lib/spikard/app.rb +61 -49
  5. data/lib/spikard/converters.rb +3 -75
  6. data/lib/spikard/handler_wrapper.rb +6 -9
  7. data/lib/spikard/provide.rb +14 -28
  8. data/lib/spikard/response.rb +75 -11
  9. data/lib/spikard/streaming_response.rb +24 -1
  10. data/lib/spikard/testing.rb +1 -1
  11. data/lib/spikard/version.rb +1 -1
  12. data/sig/spikard.rbs +14 -3
  13. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.10.0/build/buildkitd.toml +2 -0
  14. metadata +3 -80
  15. data/vendor/crates/spikard-core/Cargo.toml +0 -40
  16. data/vendor/crates/spikard-core/src/bindings/mod.rs +0 -3
  17. data/vendor/crates/spikard-core/src/bindings/response.rs +0 -133
  18. data/vendor/crates/spikard-core/src/debug.rs +0 -63
  19. data/vendor/crates/spikard-core/src/di/container.rs +0 -726
  20. data/vendor/crates/spikard-core/src/di/dependency.rs +0 -273
  21. data/vendor/crates/spikard-core/src/di/error.rs +0 -118
  22. data/vendor/crates/spikard-core/src/di/factory.rs +0 -538
  23. data/vendor/crates/spikard-core/src/di/graph.rs +0 -545
  24. data/vendor/crates/spikard-core/src/di/mod.rs +0 -192
  25. data/vendor/crates/spikard-core/src/di/resolved.rs +0 -411
  26. data/vendor/crates/spikard-core/src/di/value.rs +0 -283
  27. data/vendor/crates/spikard-core/src/http.rs +0 -153
  28. data/vendor/crates/spikard-core/src/lib.rs +0 -28
  29. data/vendor/crates/spikard-core/src/lifecycle.rs +0 -422
  30. data/vendor/crates/spikard-core/src/parameters.rs +0 -719
  31. data/vendor/crates/spikard-core/src/problem.rs +0 -310
  32. data/vendor/crates/spikard-core/src/request_data.rs +0 -189
  33. data/vendor/crates/spikard-core/src/router.rs +0 -249
  34. data/vendor/crates/spikard-core/src/schema_registry.rs +0 -183
  35. data/vendor/crates/spikard-core/src/type_hints.rs +0 -304
  36. data/vendor/crates/spikard-core/src/validation.rs +0 -699
  37. data/vendor/crates/spikard-http/Cargo.toml +0 -58
  38. data/vendor/crates/spikard-http/src/auth.rs +0 -247
  39. data/vendor/crates/spikard-http/src/background.rs +0 -249
  40. data/vendor/crates/spikard-http/src/bindings/mod.rs +0 -3
  41. data/vendor/crates/spikard-http/src/bindings/response.rs +0 -1
  42. data/vendor/crates/spikard-http/src/body_metadata.rs +0 -8
  43. data/vendor/crates/spikard-http/src/cors.rs +0 -490
  44. data/vendor/crates/spikard-http/src/debug.rs +0 -63
  45. data/vendor/crates/spikard-http/src/di_handler.rs +0 -423
  46. data/vendor/crates/spikard-http/src/handler_response.rs +0 -190
  47. data/vendor/crates/spikard-http/src/handler_trait.rs +0 -228
  48. data/vendor/crates/spikard-http/src/handler_trait_tests.rs +0 -284
  49. data/vendor/crates/spikard-http/src/lib.rs +0 -529
  50. data/vendor/crates/spikard-http/src/lifecycle/adapter.rs +0 -149
  51. data/vendor/crates/spikard-http/src/lifecycle.rs +0 -428
  52. data/vendor/crates/spikard-http/src/middleware/mod.rs +0 -285
  53. data/vendor/crates/spikard-http/src/middleware/multipart.rs +0 -86
  54. data/vendor/crates/spikard-http/src/middleware/urlencoded.rs +0 -147
  55. data/vendor/crates/spikard-http/src/middleware/validation.rs +0 -287
  56. data/vendor/crates/spikard-http/src/openapi/mod.rs +0 -309
  57. data/vendor/crates/spikard-http/src/openapi/parameter_extraction.rs +0 -190
  58. data/vendor/crates/spikard-http/src/openapi/schema_conversion.rs +0 -308
  59. data/vendor/crates/spikard-http/src/openapi/spec_generation.rs +0 -195
  60. data/vendor/crates/spikard-http/src/parameters.rs +0 -1
  61. data/vendor/crates/spikard-http/src/problem.rs +0 -1
  62. data/vendor/crates/spikard-http/src/query_parser.rs +0 -369
  63. data/vendor/crates/spikard-http/src/response.rs +0 -399
  64. data/vendor/crates/spikard-http/src/router.rs +0 -1
  65. data/vendor/crates/spikard-http/src/schema_registry.rs +0 -1
  66. data/vendor/crates/spikard-http/src/server/handler.rs +0 -80
  67. data/vendor/crates/spikard-http/src/server/lifecycle_execution.rs +0 -98
  68. data/vendor/crates/spikard-http/src/server/mod.rs +0 -805
  69. data/vendor/crates/spikard-http/src/server/request_extraction.rs +0 -119
  70. data/vendor/crates/spikard-http/src/sse.rs +0 -447
  71. data/vendor/crates/spikard-http/src/testing/form.rs +0 -14
  72. data/vendor/crates/spikard-http/src/testing/multipart.rs +0 -60
  73. data/vendor/crates/spikard-http/src/testing/test_client.rs +0 -285
  74. data/vendor/crates/spikard-http/src/testing.rs +0 -377
  75. data/vendor/crates/spikard-http/src/type_hints.rs +0 -1
  76. data/vendor/crates/spikard-http/src/validation.rs +0 -1
  77. data/vendor/crates/spikard-http/src/websocket.rs +0 -324
  78. data/vendor/crates/spikard-rb/Cargo.toml +0 -42
  79. data/vendor/crates/spikard-rb/build.rs +0 -8
  80. data/vendor/crates/spikard-rb/src/background.rs +0 -63
  81. data/vendor/crates/spikard-rb/src/config.rs +0 -294
  82. data/vendor/crates/spikard-rb/src/conversion.rs +0 -392
  83. data/vendor/crates/spikard-rb/src/di.rs +0 -409
  84. data/vendor/crates/spikard-rb/src/handler.rs +0 -534
  85. data/vendor/crates/spikard-rb/src/lib.rs +0 -2020
  86. data/vendor/crates/spikard-rb/src/lifecycle.rs +0 -267
  87. data/vendor/crates/spikard-rb/src/server.rs +0 -283
  88. data/vendor/crates/spikard-rb/src/sse.rs +0 -231
  89. data/vendor/crates/spikard-rb/src/test_client.rs +0 -404
  90. data/vendor/crates/spikard-rb/src/test_sse.rs +0 -143
  91. data/vendor/crates/spikard-rb/src/test_websocket.rs +0 -221
  92. data/vendor/crates/spikard-rb/src/websocket.rs +0 -233
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Spikard
4
- VERSION = '0.2.5'
4
+ VERSION = '0.3.0'
5
5
  end
data/sig/spikard.rbs CHANGED
@@ -143,9 +143,10 @@ module Spikard
143
143
  end
144
144
 
145
145
  class Response
146
- attr_accessor content: untyped
146
+ attr_reader content: untyped
147
147
  attr_reader status_code: Integer
148
148
  attr_reader headers: Hash[String, String]
149
+ attr_reader native_response: untyped
149
150
 
150
151
  def initialize: (
151
152
  ?content: untyped,
@@ -157,6 +158,7 @@ module Spikard
157
158
  def status: () -> Integer
158
159
  def status_code=: (Integer) -> Integer
159
160
  def headers=: (Hash[untyped, untyped]?) -> Hash[String, String]
161
+ def content=: (untyped) -> untyped
160
162
  def set_header: (String, String) -> String
161
163
  def set_cookie: (
162
164
  String,
@@ -168,14 +170,20 @@ module Spikard
168
170
  ?httponly: bool?,
169
171
  ?samesite: String?
170
172
  ) -> String
173
+ def to_native_response: () -> untyped
171
174
  end
172
175
 
173
176
  class StreamingResponse
174
177
  attr_reader stream: Enumerable[untyped]
175
178
  attr_reader status_code: Integer
176
179
  attr_reader headers: Hash[String, String]
180
+ attr_reader native_response: untyped
177
181
 
178
182
  def initialize: (Enumerable[untyped], ?status_code: Integer, ?headers: Hash[untyped, untyped]?) -> void
183
+ def to_native_response: () -> untyped
184
+ end
185
+
186
+ module Testing
179
187
  end
180
188
 
181
189
  module LifecycleHooks
@@ -184,7 +192,6 @@ module Spikard
184
192
  def pre_handler: () { (untyped) -> untyped } -> Proc
185
193
  def on_response: () { (untyped) -> untyped } -> Proc
186
194
  def on_error: () { (untyped) -> untyped } -> Proc
187
- def lifecycle_hooks: () -> Hash[Symbol, Array[Proc]]
188
195
  end
189
196
 
190
197
  module ProvideSupport
@@ -195,7 +202,7 @@ module Spikard
195
202
  ?singleton: bool,
196
203
  ?cacheable: bool
197
204
  ) ?{ (**untyped) -> untyped } -> self
198
- def dependencies: () -> Hash[String, untyped]
205
+ def dependencies: () -> Spikard::Native::DependencyRegistry
199
206
  end
200
207
 
201
208
  class App
@@ -258,6 +265,10 @@ module Spikard
258
265
  Hash[String, untyped]
259
266
  ) -> void
260
267
 
268
+ class DependencyRegistry
269
+ def initialize: () -> void
270
+ end
271
+
261
272
  class TestClient
262
273
  def initialize: (
263
274
  String,
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spikard
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Na'aman Hirschfeld
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-12-01 00:00:00.000000000 Z
11
+ date: 2025-12-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: websocket-client-simple
@@ -69,84 +69,7 @@ files:
69
69
  - lib/spikard/websocket.rb
70
70
  - sig/spikard.rbs
71
71
  - vendor/bundle/ruby/3.3.0/gems/diff-lcs-1.6.2/mise.toml
72
- - vendor/crates/spikard-core/Cargo.toml
73
- - vendor/crates/spikard-core/src/bindings/mod.rs
74
- - vendor/crates/spikard-core/src/bindings/response.rs
75
- - vendor/crates/spikard-core/src/debug.rs
76
- - vendor/crates/spikard-core/src/di/container.rs
77
- - vendor/crates/spikard-core/src/di/dependency.rs
78
- - vendor/crates/spikard-core/src/di/error.rs
79
- - vendor/crates/spikard-core/src/di/factory.rs
80
- - vendor/crates/spikard-core/src/di/graph.rs
81
- - vendor/crates/spikard-core/src/di/mod.rs
82
- - vendor/crates/spikard-core/src/di/resolved.rs
83
- - vendor/crates/spikard-core/src/di/value.rs
84
- - vendor/crates/spikard-core/src/http.rs
85
- - vendor/crates/spikard-core/src/lib.rs
86
- - vendor/crates/spikard-core/src/lifecycle.rs
87
- - vendor/crates/spikard-core/src/parameters.rs
88
- - vendor/crates/spikard-core/src/problem.rs
89
- - vendor/crates/spikard-core/src/request_data.rs
90
- - vendor/crates/spikard-core/src/router.rs
91
- - vendor/crates/spikard-core/src/schema_registry.rs
92
- - vendor/crates/spikard-core/src/type_hints.rs
93
- - vendor/crates/spikard-core/src/validation.rs
94
- - vendor/crates/spikard-http/Cargo.toml
95
- - vendor/crates/spikard-http/src/auth.rs
96
- - vendor/crates/spikard-http/src/background.rs
97
- - vendor/crates/spikard-http/src/bindings/mod.rs
98
- - vendor/crates/spikard-http/src/bindings/response.rs
99
- - vendor/crates/spikard-http/src/body_metadata.rs
100
- - vendor/crates/spikard-http/src/cors.rs
101
- - vendor/crates/spikard-http/src/debug.rs
102
- - vendor/crates/spikard-http/src/di_handler.rs
103
- - vendor/crates/spikard-http/src/handler_response.rs
104
- - vendor/crates/spikard-http/src/handler_trait.rs
105
- - vendor/crates/spikard-http/src/handler_trait_tests.rs
106
- - vendor/crates/spikard-http/src/lib.rs
107
- - vendor/crates/spikard-http/src/lifecycle.rs
108
- - vendor/crates/spikard-http/src/lifecycle/adapter.rs
109
- - vendor/crates/spikard-http/src/middleware/mod.rs
110
- - vendor/crates/spikard-http/src/middleware/multipart.rs
111
- - vendor/crates/spikard-http/src/middleware/urlencoded.rs
112
- - vendor/crates/spikard-http/src/middleware/validation.rs
113
- - vendor/crates/spikard-http/src/openapi/mod.rs
114
- - vendor/crates/spikard-http/src/openapi/parameter_extraction.rs
115
- - vendor/crates/spikard-http/src/openapi/schema_conversion.rs
116
- - vendor/crates/spikard-http/src/openapi/spec_generation.rs
117
- - vendor/crates/spikard-http/src/parameters.rs
118
- - vendor/crates/spikard-http/src/problem.rs
119
- - vendor/crates/spikard-http/src/query_parser.rs
120
- - vendor/crates/spikard-http/src/response.rs
121
- - vendor/crates/spikard-http/src/router.rs
122
- - vendor/crates/spikard-http/src/schema_registry.rs
123
- - vendor/crates/spikard-http/src/server/handler.rs
124
- - vendor/crates/spikard-http/src/server/lifecycle_execution.rs
125
- - vendor/crates/spikard-http/src/server/mod.rs
126
- - vendor/crates/spikard-http/src/server/request_extraction.rs
127
- - vendor/crates/spikard-http/src/sse.rs
128
- - vendor/crates/spikard-http/src/testing.rs
129
- - vendor/crates/spikard-http/src/testing/form.rs
130
- - vendor/crates/spikard-http/src/testing/multipart.rs
131
- - vendor/crates/spikard-http/src/testing/test_client.rs
132
- - vendor/crates/spikard-http/src/type_hints.rs
133
- - vendor/crates/spikard-http/src/validation.rs
134
- - vendor/crates/spikard-http/src/websocket.rs
135
- - vendor/crates/spikard-rb/Cargo.toml
136
- - vendor/crates/spikard-rb/build.rs
137
- - vendor/crates/spikard-rb/src/background.rs
138
- - vendor/crates/spikard-rb/src/config.rs
139
- - vendor/crates/spikard-rb/src/conversion.rs
140
- - vendor/crates/spikard-rb/src/di.rs
141
- - vendor/crates/spikard-rb/src/handler.rs
142
- - vendor/crates/spikard-rb/src/lib.rs
143
- - vendor/crates/spikard-rb/src/lifecycle.rs
144
- - vendor/crates/spikard-rb/src/server.rs
145
- - vendor/crates/spikard-rb/src/sse.rs
146
- - vendor/crates/spikard-rb/src/test_client.rs
147
- - vendor/crates/spikard-rb/src/test_sse.rs
148
- - vendor/crates/spikard-rb/src/test_websocket.rs
149
- - vendor/crates/spikard-rb/src/websocket.rs
72
+ - vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.10.0/build/buildkitd.toml
150
73
  homepage: https://github.com/Goldziher/spikard
151
74
  licenses:
152
75
  - MIT
@@ -1,40 +0,0 @@
1
- [package]
2
- name = "spikard-core"
3
- version.workspace = true
4
- edition.workspace = true
5
- authors.workspace = true
6
- license.workspace = true
7
- repository.workspace = true
8
- homepage.workspace = true
9
- description = "Shared transport-agnostic primitives for Spikard runtimes"
10
- keywords = ["http", "web", "framework", "validation", "middleware"]
11
- categories = ["web-programming::http-server", "web-programming", "development-tools"]
12
- documentation = "https://docs.rs/spikard-core"
13
- readme = "README.md"
14
-
15
- [dependencies]
16
- serde.workspace = true
17
- serde_json.workspace = true
18
- tracing.workspace = true
19
- anyhow = "1.0"
20
- jsonschema.workspace = true
21
- regex = "1"
22
- flate2 = "1.1"
23
- brotli = "8.0"
24
- http.workspace = true
25
- base64 = "0.22"
26
- serde_qs = "0.15"
27
- url = "2.5"
28
- jiff = "0.2"
29
- uuid = "1.18"
30
- indexmap = "2.12"
31
- tokio = { workspace = true, optional = true }
32
- bytes = { version = "1.11", optional = true }
33
- thiserror = { workspace = true, optional = true }
34
-
35
- [features]
36
- default = []
37
- di = ["dep:tokio", "dep:bytes", "dep:thiserror"]
38
-
39
- [dev-dependencies]
40
- tokio-test = "0.4"
@@ -1,3 +0,0 @@
1
- pub mod response;
2
-
3
- pub use response::{RawResponse, StaticAsset};
@@ -1,133 +0,0 @@
1
- use crate::CompressionConfig;
2
- use brotli::CompressorWriter;
3
- use flate2::Compression;
4
- use flate2::write::GzEncoder;
5
- use std::collections::HashMap;
6
- use std::io::Write;
7
-
8
- /// Minimal response container shared by bindings.
9
- #[derive(Clone, Debug)]
10
- pub struct RawResponse {
11
- pub status: u16,
12
- pub headers: HashMap<String, String>,
13
- pub body: Vec<u8>,
14
- }
15
-
16
- impl RawResponse {
17
- /// Construct a new response.
18
- pub fn new(status: u16, headers: HashMap<String, String>, body: Vec<u8>) -> Self {
19
- Self { status, headers, body }
20
- }
21
-
22
- /// Apply compression filters if the response qualifies.
23
- pub fn apply_compression(&mut self, request_headers: &HashMap<String, String>, compression: &CompressionConfig) {
24
- if self.body.is_empty() || self.status == 206 {
25
- return;
26
- }
27
- if self
28
- .headers
29
- .keys()
30
- .any(|key| key.eq_ignore_ascii_case("content-encoding"))
31
- {
32
- return;
33
- }
34
- if self.body.len() < compression.min_size {
35
- return;
36
- }
37
-
38
- let accept_encoding = header_value(request_headers, "Accept-Encoding").map(|value| value.to_ascii_lowercase());
39
- let accepts_brotli = accept_encoding
40
- .as_ref()
41
- .map(|value| value.contains("br"))
42
- .unwrap_or(false);
43
- if compression.brotli && accepts_brotli && self.try_compress_brotli(compression) {
44
- return;
45
- }
46
-
47
- let accepts_gzip = accept_encoding
48
- .as_ref()
49
- .map(|value| value.contains("gzip"))
50
- .unwrap_or(false);
51
- if compression.gzip && accepts_gzip {
52
- self.try_compress_gzip(compression);
53
- }
54
- }
55
-
56
- fn try_compress_brotli(&mut self, compression: &CompressionConfig) -> bool {
57
- let quality = compression.quality.min(11);
58
- let mut writer = CompressorWriter::new(Vec::new(), 4096, quality, 22);
59
- if writer.write_all(&self.body).is_err() || writer.flush().is_err() {
60
- return false;
61
- }
62
- let compressed = writer.into_inner();
63
- if compressed.is_empty() {
64
- return false;
65
- }
66
- self.finalize_encoded_body("br", compressed);
67
- true
68
- }
69
-
70
- fn try_compress_gzip(&mut self, compression: &CompressionConfig) -> bool {
71
- let mut encoder = GzEncoder::new(Vec::new(), Compression::new(compression.quality));
72
- if encoder.write_all(&self.body).is_err() {
73
- return false;
74
- }
75
- let compressed = encoder.finish().unwrap_or_else(|_| Vec::new());
76
- if compressed.is_empty() {
77
- return false;
78
- }
79
- self.finalize_encoded_body("gzip", compressed);
80
- true
81
- }
82
-
83
- fn finalize_encoded_body(&mut self, encoding: &str, compressed: Vec<u8>) {
84
- self.body = compressed;
85
- self.headers
86
- .insert("content-encoding".to_string(), encoding.to_string());
87
- self.headers.insert("vary".to_string(), "Accept-Encoding".to_string());
88
- self.headers
89
- .insert("content-length".to_string(), self.body.len().to_string());
90
- }
91
- }
92
-
93
- fn header_value<'a>(headers: &'a HashMap<String, String>, name: &str) -> Option<&'a str> {
94
- headers.iter().find_map(|(key, value)| {
95
- if key.eq_ignore_ascii_case(name) {
96
- Some(value.as_str())
97
- } else {
98
- None
99
- }
100
- })
101
- }
102
-
103
- /// Pre-rendered static asset produced by the CLI bundler.
104
- #[derive(Clone, Debug)]
105
- pub struct StaticAsset {
106
- pub route: String,
107
- pub headers: HashMap<String, String>,
108
- pub body: Vec<u8>,
109
- }
110
-
111
- impl StaticAsset {
112
- /// Build a response snapshot if the incoming request targets this asset.
113
- pub fn serve(&self, method: &str, normalized_path: &str) -> Option<RawResponse> {
114
- if !method.eq_ignore_ascii_case("GET") && !method.eq_ignore_ascii_case("HEAD") {
115
- return None;
116
- }
117
- if self.route != normalized_path {
118
- return None;
119
- }
120
-
121
- let mut headers = self.headers.clone();
122
- headers
123
- .entry("content-length".to_string())
124
- .or_insert_with(|| self.body.len().to_string());
125
- let body = if method.eq_ignore_ascii_case("HEAD") {
126
- Vec::new()
127
- } else {
128
- self.body.clone()
129
- };
130
-
131
- Some(RawResponse::new(200, headers, body))
132
- }
133
- }
@@ -1,63 +0,0 @@
1
- //! Debug logging utilities for spikard-http
2
- //!
3
- //! This module provides debug logging that can be enabled via:
4
- //! - Building in debug mode (cfg(debug_assertions))
5
- //! - Setting SPIKARD_DEBUG=1 environment variable
6
-
7
- use std::sync::atomic::{AtomicBool, Ordering};
8
-
9
- static DEBUG_ENABLED: AtomicBool = AtomicBool::new(false);
10
-
11
- /// Initialize debug logging based on environment and build mode
12
- pub fn init() {
13
- let enabled = cfg!(debug_assertions) || std::env::var("SPIKARD_DEBUG").is_ok() || std::env::var("DEBUG").is_ok();
14
-
15
- eprintln!(
16
- "[spikard-http::debug] init() called, cfg!(debug_assertions)={}, DEBUG={}, enabled={}",
17
- cfg!(debug_assertions),
18
- std::env::var("DEBUG").is_ok(),
19
- enabled
20
- );
21
-
22
- DEBUG_ENABLED.store(enabled, Ordering::Relaxed);
23
-
24
- if enabled {
25
- eprintln!("[spikard-http] Debug logging enabled");
26
- }
27
- }
28
-
29
- /// Check if debug logging is enabled
30
- #[inline]
31
- pub fn is_enabled() -> bool {
32
- DEBUG_ENABLED.load(Ordering::Relaxed)
33
- }
34
-
35
- /// Log a debug message if debugging is enabled
36
- #[macro_export]
37
- macro_rules! debug_log {
38
- ($($arg:tt)*) => {
39
- if $crate::debug::is_enabled() {
40
- eprintln!("[spikard-http] {}", format!($($arg)*));
41
- }
42
- };
43
- }
44
-
45
- /// Log a debug message with a specific module/component name
46
- #[macro_export]
47
- macro_rules! debug_log_module {
48
- ($module:expr, $($arg:tt)*) => {
49
- if $crate::debug::is_enabled() {
50
- eprintln!("[spikard-http::{}] {}", $module, format!($($arg)*));
51
- }
52
- };
53
- }
54
-
55
- /// Log a debug value with pretty-printing
56
- #[macro_export]
57
- macro_rules! debug_log_value {
58
- ($name:expr, $value:expr) => {
59
- if $crate::debug::is_enabled() {
60
- eprintln!("[spikard-http] {} = {:?}", $name, $value);
61
- }
62
- };
63
- }