spikard 0.3.0 → 0.3.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/LICENSE +1 -1
- data/README.md +659 -659
- data/ext/spikard_rb/Cargo.toml +17 -17
- data/ext/spikard_rb/extconf.rb +10 -10
- data/ext/spikard_rb/src/lib.rs +6 -6
- data/lib/spikard/app.rb +386 -386
- 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 +221 -221
- 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 +360 -360
- data/vendor/crates/spikard-core/Cargo.toml +40 -0
- data/vendor/crates/spikard-core/src/bindings/mod.rs +3 -0
- data/vendor/crates/spikard-core/src/bindings/response.rs +133 -0
- data/vendor/crates/spikard-core/src/debug.rs +63 -0
- data/vendor/crates/spikard-core/src/di/container.rs +726 -0
- data/vendor/crates/spikard-core/src/di/dependency.rs +273 -0
- data/vendor/crates/spikard-core/src/di/error.rs +118 -0
- data/vendor/crates/spikard-core/src/di/factory.rs +538 -0
- data/vendor/crates/spikard-core/src/di/graph.rs +545 -0
- data/vendor/crates/spikard-core/src/di/mod.rs +192 -0
- data/vendor/crates/spikard-core/src/di/resolved.rs +411 -0
- data/vendor/crates/spikard-core/src/di/value.rs +283 -0
- data/vendor/crates/spikard-core/src/errors.rs +39 -0
- data/vendor/crates/spikard-core/src/http.rs +153 -0
- data/vendor/crates/spikard-core/src/lib.rs +29 -0
- data/vendor/crates/spikard-core/src/lifecycle.rs +422 -0
- data/vendor/crates/spikard-core/src/parameters.rs +722 -0
- data/vendor/crates/spikard-core/src/problem.rs +310 -0
- data/vendor/crates/spikard-core/src/request_data.rs +189 -0
- data/vendor/crates/spikard-core/src/router.rs +249 -0
- data/vendor/crates/spikard-core/src/schema_registry.rs +183 -0
- data/vendor/crates/spikard-core/src/type_hints.rs +304 -0
- data/vendor/crates/spikard-core/src/validation.rs +699 -0
- data/vendor/crates/spikard-http/Cargo.toml +58 -0
- data/vendor/crates/spikard-http/src/auth.rs +247 -0
- data/vendor/crates/spikard-http/src/background.rs +249 -0
- data/vendor/crates/spikard-http/src/bindings/mod.rs +3 -0
- data/vendor/crates/spikard-http/src/bindings/response.rs +1 -0
- data/vendor/crates/spikard-http/src/body_metadata.rs +8 -0
- data/vendor/crates/spikard-http/src/cors.rs +490 -0
- data/vendor/crates/spikard-http/src/debug.rs +63 -0
- data/vendor/crates/spikard-http/src/di_handler.rs +423 -0
- data/vendor/crates/spikard-http/src/handler_response.rs +190 -0
- data/vendor/crates/spikard-http/src/handler_trait.rs +228 -0
- data/vendor/crates/spikard-http/src/handler_trait_tests.rs +284 -0
- data/vendor/crates/spikard-http/src/lib.rs +529 -0
- data/vendor/crates/spikard-http/src/lifecycle/adapter.rs +149 -0
- data/vendor/crates/spikard-http/src/lifecycle.rs +428 -0
- data/vendor/crates/spikard-http/src/middleware/mod.rs +285 -0
- data/vendor/crates/spikard-http/src/middleware/multipart.rs +86 -0
- data/vendor/crates/spikard-http/src/middleware/urlencoded.rs +147 -0
- data/vendor/crates/spikard-http/src/middleware/validation.rs +287 -0
- data/vendor/crates/spikard-http/src/openapi/mod.rs +309 -0
- data/vendor/crates/spikard-http/src/openapi/parameter_extraction.rs +190 -0
- data/vendor/crates/spikard-http/src/openapi/schema_conversion.rs +308 -0
- data/vendor/crates/spikard-http/src/openapi/spec_generation.rs +195 -0
- data/vendor/crates/spikard-http/src/parameters.rs +1 -0
- data/vendor/crates/spikard-http/src/problem.rs +1 -0
- data/vendor/crates/spikard-http/src/query_parser.rs +369 -0
- data/vendor/crates/spikard-http/src/response.rs +399 -0
- data/vendor/crates/spikard-http/src/router.rs +1 -0
- data/vendor/crates/spikard-http/src/schema_registry.rs +1 -0
- data/vendor/crates/spikard-http/src/server/handler.rs +87 -0
- data/vendor/crates/spikard-http/src/server/lifecycle_execution.rs +98 -0
- data/vendor/crates/spikard-http/src/server/mod.rs +805 -0
- data/vendor/crates/spikard-http/src/server/request_extraction.rs +119 -0
- data/vendor/crates/spikard-http/src/sse.rs +447 -0
- data/vendor/crates/spikard-http/src/testing/form.rs +14 -0
- data/vendor/crates/spikard-http/src/testing/multipart.rs +60 -0
- data/vendor/crates/spikard-http/src/testing/test_client.rs +285 -0
- data/vendor/crates/spikard-http/src/testing.rs +377 -0
- data/vendor/crates/spikard-http/src/type_hints.rs +1 -0
- data/vendor/crates/spikard-http/src/validation.rs +1 -0
- data/vendor/crates/spikard-http/src/websocket.rs +324 -0
- data/vendor/crates/spikard-rb/Cargo.toml +42 -0
- data/vendor/crates/spikard-rb/build.rs +8 -0
- data/vendor/crates/spikard-rb/src/background.rs +63 -0
- data/vendor/crates/spikard-rb/src/config.rs +294 -0
- data/vendor/crates/spikard-rb/src/conversion.rs +453 -0
- data/vendor/crates/spikard-rb/src/di.rs +409 -0
- data/vendor/crates/spikard-rb/src/handler.rs +625 -0
- data/vendor/crates/spikard-rb/src/lib.rs +2771 -0
- data/vendor/crates/spikard-rb/src/lifecycle.rs +274 -0
- data/vendor/crates/spikard-rb/src/server.rs +283 -0
- data/vendor/crates/spikard-rb/src/sse.rs +231 -0
- data/vendor/crates/spikard-rb/src/test_client.rs +404 -0
- data/vendor/crates/spikard-rb/src/test_sse.rs +143 -0
- data/vendor/crates/spikard-rb/src/test_websocket.rs +221 -0
- data/vendor/crates/spikard-rb/src/websocket.rs +233 -0
- data/vendor/spikard-core/Cargo.toml +40 -0
- data/vendor/spikard-core/src/bindings/mod.rs +3 -0
- data/vendor/spikard-core/src/bindings/response.rs +133 -0
- data/vendor/spikard-core/src/debug.rs +63 -0
- data/vendor/spikard-core/src/di/container.rs +726 -0
- data/vendor/spikard-core/src/di/dependency.rs +273 -0
- data/vendor/spikard-core/src/di/error.rs +118 -0
- data/vendor/spikard-core/src/di/factory.rs +538 -0
- data/vendor/spikard-core/src/di/graph.rs +545 -0
- data/vendor/spikard-core/src/di/mod.rs +192 -0
- data/vendor/spikard-core/src/di/resolved.rs +411 -0
- data/vendor/spikard-core/src/di/value.rs +283 -0
- data/vendor/spikard-core/src/http.rs +153 -0
- data/vendor/spikard-core/src/lib.rs +28 -0
- data/vendor/spikard-core/src/lifecycle.rs +422 -0
- data/vendor/spikard-core/src/parameters.rs +719 -0
- data/vendor/spikard-core/src/problem.rs +310 -0
- data/vendor/spikard-core/src/request_data.rs +189 -0
- data/vendor/spikard-core/src/router.rs +249 -0
- data/vendor/spikard-core/src/schema_registry.rs +183 -0
- data/vendor/spikard-core/src/type_hints.rs +304 -0
- data/vendor/spikard-core/src/validation.rs +699 -0
- data/vendor/spikard-http/Cargo.toml +58 -0
- data/vendor/spikard-http/src/auth.rs +247 -0
- data/vendor/spikard-http/src/background.rs +249 -0
- data/vendor/spikard-http/src/bindings/mod.rs +3 -0
- data/vendor/spikard-http/src/bindings/response.rs +1 -0
- data/vendor/spikard-http/src/body_metadata.rs +8 -0
- data/vendor/spikard-http/src/cors.rs +490 -0
- data/vendor/spikard-http/src/debug.rs +63 -0
- data/vendor/spikard-http/src/di_handler.rs +423 -0
- data/vendor/spikard-http/src/handler_response.rs +190 -0
- data/vendor/spikard-http/src/handler_trait.rs +228 -0
- data/vendor/spikard-http/src/handler_trait_tests.rs +284 -0
- data/vendor/spikard-http/src/lib.rs +529 -0
- data/vendor/spikard-http/src/lifecycle/adapter.rs +149 -0
- data/vendor/spikard-http/src/lifecycle.rs +428 -0
- data/vendor/spikard-http/src/middleware/mod.rs +285 -0
- data/vendor/spikard-http/src/middleware/multipart.rs +86 -0
- data/vendor/spikard-http/src/middleware/urlencoded.rs +147 -0
- data/vendor/spikard-http/src/middleware/validation.rs +287 -0
- data/vendor/spikard-http/src/openapi/mod.rs +309 -0
- data/vendor/spikard-http/src/openapi/parameter_extraction.rs +190 -0
- data/vendor/spikard-http/src/openapi/schema_conversion.rs +308 -0
- data/vendor/spikard-http/src/openapi/spec_generation.rs +195 -0
- data/vendor/spikard-http/src/parameters.rs +1 -0
- data/vendor/spikard-http/src/problem.rs +1 -0
- data/vendor/spikard-http/src/query_parser.rs +369 -0
- data/vendor/spikard-http/src/response.rs +399 -0
- data/vendor/spikard-http/src/router.rs +1 -0
- data/vendor/spikard-http/src/schema_registry.rs +1 -0
- data/vendor/spikard-http/src/server/handler.rs +80 -0
- data/vendor/spikard-http/src/server/lifecycle_execution.rs +98 -0
- data/vendor/spikard-http/src/server/mod.rs +805 -0
- data/vendor/spikard-http/src/server/request_extraction.rs +119 -0
- data/vendor/spikard-http/src/sse.rs +447 -0
- data/vendor/spikard-http/src/testing/form.rs +14 -0
- data/vendor/spikard-http/src/testing/multipart.rs +60 -0
- data/vendor/spikard-http/src/testing/test_client.rs +285 -0
- data/vendor/spikard-http/src/testing.rs +377 -0
- data/vendor/spikard-http/src/type_hints.rs +1 -0
- data/vendor/spikard-http/src/validation.rs +1 -0
- data/vendor/spikard-http/src/websocket.rs +324 -0
- data/vendor/spikard-rb/Cargo.toml +42 -0
- data/vendor/spikard-rb/build.rs +8 -0
- data/vendor/spikard-rb/src/background.rs +63 -0
- data/vendor/spikard-rb/src/config.rs +294 -0
- data/vendor/spikard-rb/src/conversion.rs +392 -0
- data/vendor/spikard-rb/src/di.rs +409 -0
- data/vendor/spikard-rb/src/handler.rs +534 -0
- data/vendor/spikard-rb/src/lib.rs +2020 -0
- data/vendor/spikard-rb/src/lifecycle.rs +267 -0
- data/vendor/spikard-rb/src/server.rs +283 -0
- data/vendor/spikard-rb/src/sse.rs +231 -0
- data/vendor/spikard-rb/src/test_client.rs +404 -0
- data/vendor/spikard-rb/src/test_sse.rs +143 -0
- data/vendor/spikard-rb/src/test_websocket.rs +221 -0
- data/vendor/spikard-rb/src/websocket.rs +233 -0
- metadata +162 -8
- /data/vendor/bundle/ruby/{3.3.0 → 3.4.0}/gems/diff-lcs-1.6.2/mise.toml +0 -0
- /data/vendor/bundle/ruby/{3.3.0 → 3.4.0}/gems/rake-compiler-dock-1.10.0/build/buildkitd.toml +0 -0
|
@@ -0,0 +1,40 @@
|
|
|
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"
|
|
@@ -0,0 +1,133 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
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
|
+
}
|