From fcaa68f95ab4cd70327137a744367808926eb72c Mon Sep 17 00:00:00 2001 From: Brian Hardock Date: Wed, 27 May 2026 12:11:59 -0600 Subject: [PATCH] Re-introduce http::router (opt-in) Signed-off-by: Brian Hardock --- Cargo.lock | 38 + crates/spin-sdk/Cargo.toml | 3 + crates/spin-sdk/src/http.rs | 4 + crates/spin-sdk/src/http/router.rs | 348 +++++ crates/spin-sdk/src/test.rs | 141 ++ .../test-cases/http-router/Cargo.lock | 1266 +++++++++++++++++ .../test-cases/http-router/Cargo.toml | 16 + .../test-cases/http-router/src/lib.rs | 57 + .../test-cases/simple-http/Cargo.lock | 94 +- .../test-cases/simple-redis/Cargo.lock | 94 +- 10 files changed, 1963 insertions(+), 98 deletions(-) create mode 100644 crates/spin-sdk/src/http/router.rs create mode 100644 crates/spin-sdk/test-cases/http-router/Cargo.lock create mode 100644 crates/spin-sdk/test-cases/http-router/Cargo.toml create mode 100644 crates/spin-sdk/test-cases/http-router/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 6179d57..a0424b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1918,6 +1918,16 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "routefinder" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0971d3c8943a6267d6bd0d782fdc4afa7593e7381a92a3df950ff58897e066b5" +dependencies = [ + "smartcow", + "smartstring", +] + [[package]] name = "rust-key-value" version = "0.1.0" @@ -2206,6 +2216,26 @@ dependencies = [ "serde", ] +[[package]] +name = "smartcow" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "656fcb1c1fca8c4655372134ce87d8afdf5ec5949ebabe8d314be0141d8b5da2" +dependencies = [ + "smartstring", +] + +[[package]] +name = "smartstring" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29" +dependencies = [ + "autocfg", + "static_assertions", + "version_check", +] + [[package]] name = "socket2" version = "0.6.3" @@ -2239,6 +2269,7 @@ name = "spin-sdk" version = "6.0.0" dependencies = [ "anyhow", + "async-trait", "bytes", "chrono", "futures", @@ -2247,6 +2278,7 @@ dependencies = [ "http-body-util", "hyper", "postgres_range", + "routefinder", "rust_decimal", "serde", "serde_json", @@ -2292,6 +2324,12 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "streaming" version = "0.1.0" diff --git a/crates/spin-sdk/Cargo.toml b/crates/spin-sdk/Cargo.toml index 5d98251..cfe2693 100644 --- a/crates/spin-sdk/Cargo.toml +++ b/crates/spin-sdk/Cargo.toml @@ -24,6 +24,7 @@ name = "spin_sdk" default = ["http", "key-value", "json", "llm", "mqtt", "mysql", "pg", "postgres4-types", "redis", "sqlite", "variables", "export-sdk-language"] export-sdk-language = [] http = ["dep:bytes", "dep:http-body", "dep:http-body-util", "dep:hyperium"] +router = ["http", "dep:async-trait", "dep:routefinder"] grpc = ["http", "dep:tower-service"] key-value = [] json = ["dep:serde", "dep:serde_json"] @@ -48,6 +49,8 @@ bytes = { version = "1.11.1", optional = true } http-body = { version = "1.0.1", optional = true } http-body-util = { version = "0.1.3", optional = true } hyperium = { package = "http", version = "1.3.1", optional = true } +async-trait = { version = "0.1", optional = true } +routefinder = { version = "0.5", optional = true } # grpc tower-service = { version = "0.3", optional = true } diff --git a/crates/spin-sdk/src/http.rs b/crates/spin-sdk/src/http.rs index 638eb60..53f647f 100644 --- a/crates/spin-sdk/src/http.rs +++ b/crates/spin-sdk/src/http.rs @@ -16,6 +16,10 @@ pub mod body; #[cfg(feature = "grpc")] #[cfg_attr(docsrs, doc(cfg(feature = "grpc")))] pub mod grpc; +/// An HTTP request router with pattern-matched paths and per-method handlers. +#[cfg(feature = "router")] +#[cfg_attr(docsrs, doc(cfg(feature = "router")))] +pub mod router; /// A alias for [`std::result::Result`] that uses [`Error`] as the default error type. /// diff --git a/crates/spin-sdk/src/http/router.rs b/crates/spin-sdk/src/http/router.rs new file mode 100644 index 0000000..ed952ef --- /dev/null +++ b/crates/spin-sdk/src/http/router.rs @@ -0,0 +1,348 @@ +// This router implementation is heavily inspired by the `Endpoint` type in the https://github.com/http-rs/tide project. + +use super::{HttpResult, IntoResponse, Request}; +use async_trait::async_trait; +use hyperium::{Method, StatusCode}; +use routefinder::{Captures, Router as MethodRouter}; +use std::future::Future; +use std::{collections::HashMap, fmt::Display}; +use wasip3::http::types; +use wasip3::http_compat::IncomingRequestBody; + +/// The output of a router-dispatched handler: a low-level WASI HTTP response +/// (or error code), suitable for returning directly from an `#[http_service]` +/// handler. +type HandlerOutput = HttpResult; + +/// An HTTP request handler. +/// +/// This trait is automatically implemented for `Fn` types, and so is rarely +/// implemented directly by Spin users. +#[async_trait(?Send)] +pub trait Handler { + /// Invoke the handler. + async fn handle(&self, req: Request, params: Params) -> HandlerOutput; +} + +#[async_trait(?Send)] +impl Handler for Box> { + async fn handle(&self, req: Request, params: Params) -> HandlerOutput { + self.as_ref().handle(req, params).await + } +} + +#[async_trait(?Send)] +impl Handler for F +where + B: 'static, + F: Fn(Request, Params) -> Fut + 'static, + Fut: Future + 'static, +{ + async fn handle(&self, req: Request, params: Params) -> HandlerOutput { + (self)(req, params).await + } +} + +/// Route parameters extracted from a URI that match a route pattern. +pub type Params = Captures<'static, 'static>; + +/// Routes HTTP requests within a Spin component. +/// +/// Routes may contain wildcards: +/// +/// * `:name` is a single segment wildcard. The handler can retrieve it using +/// [Params::get()]. +/// * `*` is a trailing wildcard (matches anything). The handler can retrieve it +/// using [Params::wildcard()]. +/// +/// If a request matches more than one route, the match is selected according to +/// the following criteria: +/// +/// * An exact route takes priority over any wildcard. +/// * A single segment wildcard takes priority over a trailing wildcard. +/// +/// (This is the same logic as overlapping routes in the Spin manifest.) +/// +/// # Examples +/// +/// Handle GET requests to a path with a wildcard, falling back to "not found": +/// +/// ```ignore +/// use spin_sdk::http::{IntoResponse, Request, StatusCode}; +/// use spin_sdk::http::router::{Params, Router}; +/// use spin_sdk::http_service; +/// +/// #[http_service] +/// async fn handle_route(req: Request) -> impl IntoResponse { +/// let mut router = Router::new(); +/// router.get("/hello/:planet", hello_planet); +/// router.any("/*", not_found); +/// router.handle(req).await +/// } +/// +/// async fn hello_planet(_req: Request, params: Params) -> impl IntoResponse { +/// let planet = params.get("planet").unwrap_or("world").to_owned(); +/// (StatusCode::OK, format!("hello, {planet}")) +/// } +/// +/// async fn not_found(_req: Request, _params: Params) -> impl IntoResponse { +/// (StatusCode::NOT_FOUND, "not found") +/// } +/// ``` +pub struct Router { + methods_map: HashMap>>>, + any_methods: MethodRouter>>, + route_on: RouteOn, +} + +/// Describes what part of the path the Router will route on. +enum RouteOn { + /// The router will route on the full path. + FullPath, + /// The router expects the component to be handling a route with a trailing + /// wildcard (e.g. `route = /shop/...`), and will route on the trailing + /// segment. + Suffix, +} + +impl Default for Router { + fn default() -> Router { + Router::new() + } +} + +impl Display for Router { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + writeln!(f, "Registered routes:")?; + for (method, router) in &self.methods_map { + for route in router.iter() { + writeln!(f, "- {}: {}", method, route.0)?; + } + } + Ok(()) + } +} + +struct RouteMatch<'a, B> { + params: Captures<'static, 'static>, + handler: &'a dyn Handler, +} + +impl Router { + /// Asynchronously dispatches a request to the appropriate handler along + /// with the URI parameters. + pub async fn handle(&self, request: Request) -> HandlerOutput { + let method = request.method().clone(); + let path: String = match self.route_on { + RouteOn::FullPath => request.uri().path().to_owned(), + RouteOn::Suffix => match trailing_suffix(&request) { + Some(path) => path.to_owned(), + None => { + eprintln!( + "Internal error: Router configured with suffix routing but trigger route has no trailing wildcard" + ); + return StatusCode::INTERNAL_SERVER_ERROR.into_response(); + } + }, + }; + let RouteMatch { params, handler } = self.find(&path, method); + handler.handle(request, params).await + } + + fn find(&self, path: &str, method: Method) -> RouteMatch<'_, B> { + let best_match = self + .methods_map + .get(&method) + .and_then(|r| r.best_match(path)); + + if let Some(m) = best_match { + let params = m.captures().into_owned(); + let handler = m.handler(); + return RouteMatch { handler, params }; + } + + let best_match = self.any_methods.best_match(path); + + match best_match { + Some(m) => { + let params = m.captures().into_owned(); + let handler = m.handler(); + RouteMatch { handler, params } + } + None if method == Method::HEAD => { + // If it is a HTTP HEAD request then check if there is a + // callback in the methods map; if not then fall back to the + // behavior of HTTP GET; else proceed as usual. + self.find(path, Method::GET) + } + None => { + // Handle the failure case where no match could be resolved. + self.fail(path, method) + } + } + } + + // Helper function to handle the case where a best match couldn't be + // resolved. + fn fail(&self, path: &str, method: Method) -> RouteMatch<'_, B> { + // First, filter all routers to determine if the path can match but the + // provided method is not allowed. + let is_method_not_allowed = self + .methods_map + .iter() + .filter(|(k, _)| **k != method) + .any(|(_, r)| r.best_match(path).is_some()); + + if is_method_not_allowed { + // If this `path` can be handled by a callback registered with a + // different HTTP method, return 405 Method Not Allowed. + RouteMatch { + handler: &method_not_allowed::, + params: Captures::default(), + } + } else { + // ... Otherwise, nothing matched so 404. + RouteMatch { + handler: ¬_found::, + params: Captures::default(), + } + } + } + + /// Register an async handler at the path for all methods. + pub fn any(&mut self, path: &str, handler: F) + where + F: Fn(Request, Params) -> Fut + 'static, + Fut: Future + 'static, + O: IntoResponse + 'static, + { + let wrapped = move |req, params| { + let fut = handler(req, params); + async move { fut.await.into_response() } + }; + + self.any_methods.add(path, Box::new(wrapped)).unwrap(); + } + + /// Register an async handler at the path for the specified HTTP method. + pub fn add(&mut self, path: &str, method: Method, handler: F) + where + F: Fn(Request, Params) -> Fut + 'static, + Fut: Future + 'static, + O: IntoResponse + 'static, + { + let wrapped = move |req, params| { + let fut = handler(req, params); + async move { fut.await.into_response() } + }; + + self.methods_map + .entry(method) + .or_default() + .add(path, Box::new(wrapped)) + .unwrap(); + } + + /// Register an async handler at the path for the HTTP GET method. + pub fn get(&mut self, path: &str, handler: F) + where + F: Fn(Request, Params) -> Fut + 'static, + Fut: Future + 'static, + Resp: IntoResponse + 'static, + { + self.add(path, Method::GET, handler) + } + + /// Register an async handler at the path for the HTTP HEAD method. + pub fn head(&mut self, path: &str, handler: F) + where + F: Fn(Request, Params) -> Fut + 'static, + Fut: Future + 'static, + Resp: IntoResponse + 'static, + { + self.add(path, Method::HEAD, handler) + } + + /// Register an async handler at the path for the HTTP POST method. + pub fn post(&mut self, path: &str, handler: F) + where + F: Fn(Request, Params) -> Fut + 'static, + Fut: Future + 'static, + Resp: IntoResponse + 'static, + { + self.add(path, Method::POST, handler) + } + + /// Register an async handler at the path for the HTTP DELETE method. + pub fn delete(&mut self, path: &str, handler: F) + where + F: Fn(Request, Params) -> Fut + 'static, + Fut: Future + 'static, + Resp: IntoResponse + 'static, + { + self.add(path, Method::DELETE, handler) + } + + /// Register an async handler at the path for the HTTP PUT method. + pub fn put(&mut self, path: &str, handler: F) + where + F: Fn(Request, Params) -> Fut + 'static, + Fut: Future + 'static, + Resp: IntoResponse + 'static, + { + self.add(path, Method::PUT, handler) + } + + /// Register an async handler at the path for the HTTP PATCH method. + pub fn patch(&mut self, path: &str, handler: F) + where + F: Fn(Request, Params) -> Fut + 'static, + Fut: Future + 'static, + Resp: IntoResponse + 'static, + { + self.add(path, Method::PATCH, handler) + } + + /// Register an async handler at the path for the HTTP OPTIONS method. + pub fn options(&mut self, path: &str, handler: F) + where + F: Fn(Request, Params) -> Fut + 'static, + Fut: Future + 'static, + Resp: IntoResponse + 'static, + { + self.add(path, Method::OPTIONS, handler) + } + + /// Construct a new Router that matches on the full path. + pub fn new() -> Self { + Router { + methods_map: HashMap::default(), + any_methods: MethodRouter::new(), + route_on: RouteOn::FullPath, + } + } + + /// Construct a new Router that matches on the trailing wildcard component + /// of the route. + pub fn suffix() -> Self { + Router { + methods_map: HashMap::default(), + any_methods: MethodRouter::new(), + route_on: RouteOn::Suffix, + } + } +} + +async fn not_found(_req: Request, _params: Params) -> HandlerOutput { + StatusCode::NOT_FOUND.into_response() +} + +async fn method_not_allowed(_req: Request, _params: Params) -> HandlerOutput { + StatusCode::METHOD_NOT_ALLOWED.into_response() +} + +fn trailing_suffix(req: &Request) -> Option<&str> { + req.headers() + .get("spin-path-info") + .and_then(|v| v.to_str().ok()) +} diff --git a/crates/spin-sdk/src/test.rs b/crates/spin-sdk/src/test.rs index f3f05a3..b4b820a 100644 --- a/crates/spin-sdk/src/test.rs +++ b/crates/spin-sdk/src/test.rs @@ -156,3 +156,144 @@ async fn simple_redis() -> Result<()> { Ok(()) } + +mod http_router { + use super::*; + use crate::http::{FullBody, Request as HttpRequest}; + use bytes::Bytes; + use hyperium::{Method, StatusCode}; + use tokio::sync::OnceCell; + + static COMPONENT_BYTES: OnceCell> = OnceCell::const_new(); + + async fn component() -> Result { + let bytes = COMPONENT_BYTES + .get_or_try_init(|| async { build_component("http-router").await }) + .await?; + Ok(Component::new(engine(), bytes)?) + } + + async fn dispatch( + component: &Component, + request: HttpRequest>, + ) -> Result<(StatusCode, Bytes)> { + let (mut store, linker) = store_and_linker()?; + let (request, fut) = wasmtime_wasi_http::p3::Request::from_http(request); + let http_service = wasmtime_wasi_http::p3::bindings::Service::instantiate_async( + &mut store, component, &linker, + ) + .await?; + + store + .run_concurrent(async |accessor| { + let resp_fut = async { + let resp = http_service.handle(accessor, request).await??; + let resp = accessor.with(|access| resp.into_http(access, async { Ok(()) }))?; + let status = resp.status(); + let body = resp.into_body().collect().await?.to_bytes(); + anyhow::Ok((status, body)) + }; + let (status_body, ()) = tokio::try_join!(resp_fut, async { + fut.await.map_err(|e| anyhow::anyhow!("{e:?}")) + })?; + anyhow::Ok(status_body) + }) + .await? + } + + fn empty(method: Method, path: &str) -> HttpRequest> { + HttpRequest::builder() + .method(method) + .uri(format!("http://localhost{path}")) + .body(FullBody::new(Bytes::new())) + .unwrap() + } + + #[tokio::test] + async fn named_capture() -> Result<()> { + let component = component().await?; + let (status, body) = dispatch(&component, empty(Method::GET, "/hello/spin")).await?; + assert_eq!(status, StatusCode::OK); + assert_eq!(body.as_ref(), b"hello, spin"); + Ok(()) + } + + #[tokio::test] + async fn multi_capture() -> Result<()> { + let component = component().await?; + let (status, body) = dispatch(&component, empty(Method::GET, "/multiply/6/7")).await?; + assert_eq!(status, StatusCode::OK); + assert_eq!(body.as_ref(), b"42"); + Ok(()) + } + + #[tokio::test] + async fn wildcard() -> Result<()> { + let component = component().await?; + let (status, body) = dispatch(&component, empty(Method::GET, "/wild/a/b/c")).await?; + assert_eq!(status, StatusCode::OK); + assert_eq!(body.as_ref(), b"a/b/c"); + Ok(()) + } + + #[tokio::test] + async fn echo_post_body() -> Result<()> { + let component = component().await?; + let request = HttpRequest::builder() + .method(Method::POST) + .uri("http://localhost/echo") + .body(FullBody::new(Bytes::copy_from_slice(b"ping"))) + .unwrap(); + let (status, body) = dispatch(&component, request).await?; + assert_eq!(status, StatusCode::OK); + assert_eq!(body.as_ref(), b"ping"); + Ok(()) + } + + #[tokio::test] + async fn put_handler_registered_without_macro() -> Result<()> { + let component = component().await?; + let (status, body) = dispatch(&component, empty(Method::PUT, "/widgets/abc")).await?; + assert_eq!(status, StatusCode::OK); + assert_eq!(body.as_ref(), b"updated widget abc"); + Ok(()) + } + + #[tokio::test] + async fn any_method_via_closure() -> Result<()> { + let component = component().await?; + let (status, body) = dispatch(&component, empty(Method::DELETE, "/teapot")).await?; + assert_eq!(status, StatusCode::IM_A_TEAPOT); + assert_eq!(body.as_ref(), b"short and stout"); + Ok(()) + } + + #[tokio::test] + async fn method_not_allowed_when_path_matches_other_method() -> Result<()> { + let component = component().await?; + // /multiply/:x/:y is registered for GET only; the catch-all `/*` exists + // but the router should prefer 405 for a path that matches a known + // route under a different method. + let (status, _) = dispatch(&component, empty(Method::POST, "/multiply/2/3")).await?; + assert_eq!(status, StatusCode::METHOD_NOT_ALLOWED); + Ok(()) + } + + #[tokio::test] + async fn catch_all_for_unknown_path() -> Result<()> { + let component = component().await?; + let (status, _) = dispatch(&component, empty(Method::GET, "/nope")).await?; + assert_eq!(status, StatusCode::NOT_FOUND); + Ok(()) + } + + #[tokio::test] + async fn head_falls_back_to_get() -> Result<()> { + let component = component().await?; + // No HEAD handler is registered; the router should reuse the GET + // handler for /hello/:name. + let (status, _) = dispatch(&component, empty(Method::HEAD, "/hello/spin")).await?; + assert_eq!(status, StatusCode::OK); + Ok(()) + } +} diff --git a/crates/spin-sdk/test-cases/http-router/Cargo.lock b/crates/spin-sdk/test-cases/http-router/Cargo.lock new file mode 100644 index 0000000..f31b95c --- /dev/null +++ b/crates/spin-sdk/test-cases/http-router/Cargo.lock @@ -0,0 +1,1266 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "async-trait" +version = "0.1.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bitflags" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" + +[[package]] +name = "block-buffer" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be" +dependencies = [ + "hybrid-array", +] + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" + +[[package]] +name = "cc" +version = "1.2.62" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "chacha20" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" +dependencies = [ + "cfg-if", + "cpufeatures", + "rand_core", +] + +[[package]] +name = "chrono" +version = "0.4.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-link", +] + +[[package]] +name = "cmov" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f88a43d011fc4a6876cb7344703e297c71dda42494fee094d5f7c76bf13f746" + +[[package]] +name = "const-oid" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "cpufeatures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" +dependencies = [ + "hybrid-array", +] + +[[package]] +name = "ctutils" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" +dependencies = [ + "cmov", +] + +[[package]] +name = "digest" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "ctutils", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "futures" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" + +[[package]] +name = "futures-executor" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" + +[[package]] +name = "futures-macro" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "futures-sink" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" + +[[package]] +name = "futures-task" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" + +[[package]] +name = "futures-util" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "slab", +] + +[[package]] +name = "getrandom" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "rand_core", + "wasip2", + "wasip3 0.4.0+wasi-0.3.0-rc-2026-01-06", +] + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "foldhash 0.1.5", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" +dependencies = [ + "foldhash 0.2.0", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hmac" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" +dependencies = [ + "digest", +] + +[[package]] +name = "http" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be7462df143984c4598a256ef469b251d7d7f9e271135073e78fc535414f3d0" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "http-router" +version = "0.1.0" +dependencies = [ + "anyhow", + "bytes", + "http", + "http-body-util", + "spin-sdk", +] + +[[package]] +name = "hybrid-array" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da" +dependencies = [ + "typenum", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + +[[package]] +name = "indexmap" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +dependencies = [ + "equivalent", + "hashbrown 0.17.1", + "serde", + "serde_core", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "js-sys" +version = "0.3.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "142bc4740e452c1e57ade0cbc129f139c9093e354346f0872ef985f4f5cf5f11" +dependencies = [ + "cfg-if", + "futures-util", + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + +[[package]] +name = "libc" +version = "0.2.186" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" + +[[package]] +name = "log" +version = "0.4.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616ec5685824bcc94416c6d4a7a446eea774a31efd7062c8480ba6fd06d7a6e5" + +[[package]] +name = "md-5" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69b6441f590336821bb897fb28fc622898ccceb1d6cea3fde5ea86b090c4de98" +dependencies = [ + "cfg-if", + "digest", +] + +[[package]] +name = "memchr" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "postgres-protocol" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56201207dac53e2f38e848e31b4b91616a6bb6e0c7205b77718994a7f49e70fc" +dependencies = [ + "base64", + "byteorder", + "bytes", + "fallible-iterator", + "hmac", + "md-5", + "memchr", + "rand", + "sha2", + "stringprep", +] + +[[package]] +name = "postgres-types" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dc729a129e682e8d24170cd30ae1aa01b336b096cbb56df6d534ffec133d186" +dependencies = [ + "bytes", + "fallible-iterator", + "postgres-protocol", +] + +[[package]] +name = "postgres_range" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6dce28dc5ba143d8eb157b62aac01ae5a1c585c40792158b720e86a87642101" +dependencies = [ + "postgres-protocol", + "postgres-types", +] + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn 2.0.117", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] +name = "rand" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" +dependencies = [ + "chacha20", + "getrandom", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" + +[[package]] +name = "routefinder" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0971d3c8943a6267d6bd0d782fdc4afa7593e7381a92a3df950ff58897e066b5" +dependencies = [ + "smartcow", + "smartstring", +] + +[[package]] +name = "rust_decimal" +version = "1.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c5108e3d4d903e21aac27f12ba5377b6b34f9f44b325e4894c7924169d06995" +dependencies = [ + "arrayvec", + "num-traits", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "serde_json" +version = "1.0.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "sha2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smartcow" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "656fcb1c1fca8c4655372134ce87d8afdf5ec5949ebabe8d314be0141d8b5da2" +dependencies = [ + "smartstring", +] + +[[package]] +name = "smartstring" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29" +dependencies = [ + "autocfg", + "static_assertions", + "version_check", +] + +[[package]] +name = "spin-macro" +version = "6.0.0" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "spin-sdk" +version = "6.0.0" +dependencies = [ + "anyhow", + "async-trait", + "bytes", + "chrono", + "futures", + "http", + "http-body", + "http-body-util", + "postgres_range", + "routefinder", + "rust_decimal", + "serde", + "serde_json", + "spin-macro", + "thiserror", + "uuid", + "wasip3 0.6.0+wasi-0.3.0-rc-2026-03-15", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "stringprep" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" +dependencies = [ + "unicode-bidi", + "unicode-normalization", + "unicode-properties", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "tinyvec" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "typenum" +version = "1.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" + +[[package]] +name = "unicode-bidi" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "unicode-normalization" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-properties" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "uuid" +version = "1.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasip2" +version = "1.0.3+wasi-0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" +dependencies = [ + "wit-bindgen 0.57.1", +] + +[[package]] +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +dependencies = [ + "wit-bindgen 0.51.0", +] + +[[package]] +name = "wasip3" +version = "0.6.0+wasi-0.3.0-rc-2026-03-15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed83456dd6a0b8581998c0365e4651fa2997e5093b49243b7f35391afaa7a3d9" +dependencies = [ + "bytes", + "http", + "http-body", + "thiserror", + "wit-bindgen 0.57.1", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.122" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed04576f974d2b2fba0f38c51dbc5518011e38c36bf1143164be765528fd409" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.122" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "916151b09da36bd82f6615cbf3a419e2f0ba23a03c6160e8e92eb6bd4aa1dec6" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.122" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "299047362ccbfce148b67ab7e73349f77748e00c8296f9542adfad2ad82c5c5e" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 2.0.117", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.122" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a929b2c61f11ba3e9bc35b50c1f25cb38e0e892c0c231ae2b8cf78d5dad4437" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser 0.244.0", +] + +[[package]] +name = "wasm-encoder" +version = "0.247.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b6733b8b91d010a6ac5b0fb237dc46a19650bc4c67db66857e2e787d437204" +dependencies = [ + "leb128fmt", + "wasmparser 0.247.0", +] + +[[package]] +name = "wasm-metadata" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap", + "wasm-encoder 0.244.0", + "wasmparser 0.244.0", +] + +[[package]] +name = "wasm-metadata" +version = "0.247.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "665fe59e56cc9b419ca6fcca56673e3421d1a5011e3b65caf6b726fd9e041d10" +dependencies = [ + "anyhow", + "indexmap", + "wasm-encoder 0.247.0", + "wasmparser 0.247.0", +] + +[[package]] +name = "wasmparser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +dependencies = [ + "bitflags", + "hashbrown 0.15.5", + "indexmap", + "semver", +] + +[[package]] +name = "wasmparser" +version = "0.247.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e6fb4c2bee46c5ea4d40f8cdb5c131725cd976718ec56f1c8e82fbde5fa2a80" +dependencies = [ + "bitflags", + "hashbrown 0.17.1", + "indexmap", + "semver", +] + +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", +] + +[[package]] +name = "wit-bindgen" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro 0.51.0", +] + +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" +dependencies = [ + "bitflags", + "futures", + "wit-bindgen-rust-macro 0.57.1", +] + +[[package]] +name = "wit-bindgen-core" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck", + "wit-parser 0.244.0", +] + +[[package]] +name = "wit-bindgen-core" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02dee27a2dc20d1008016c742ec9fc6ea498492994ba3750be7454cbc97ff04c" +dependencies = [ + "anyhow", + "heck", + "wit-parser 0.247.0", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck", + "indexmap", + "prettyplease", + "syn 2.0.117", + "wasm-metadata 0.244.0", + "wit-bindgen-core 0.51.0", + "wit-component 0.244.0", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5007dae772945b7a5003d69d90a3a4a78929d41f19d004e980c4259a6af4484" +dependencies = [ + "anyhow", + "heck", + "indexmap", + "prettyplease", + "syn 2.0.117", + "wasm-metadata 0.247.0", + "wit-bindgen-core 0.57.1", + "wit-component 0.247.0", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn 2.0.117", + "wit-bindgen-core 0.51.0", + "wit-bindgen-rust 0.51.0", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af9237d678e3513ad24e96fe98beacdc0db6405284ba2a2400418cf0d42caa89" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn 2.0.117", + "wit-bindgen-core 0.57.1", + "wit-bindgen-rust 0.57.1", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags", + "indexmap", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder 0.244.0", + "wasm-metadata 0.244.0", + "wasmparser 0.244.0", + "wit-parser 0.244.0", +] + +[[package]] +name = "wit-component" +version = "0.247.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d567162a6b9843080e5e0053f696623ff694bae8ae017c9ec536d1873bbe3d8" +dependencies = [ + "anyhow", + "bitflags", + "indexmap", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder 0.247.0", + "wasm-metadata 0.247.0", + "wasmparser 0.247.0", + "wit-parser 0.247.0", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser 0.244.0", +] + +[[package]] +name = "wit-parser" +version = "0.247.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ffe4064318cdf3c08cb99343b44c039fcefe61ccdf58aa9975285f13d74d1fc" +dependencies = [ + "anyhow", + "hashbrown 0.17.1", + "id-arena", + "indexmap", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser 0.247.0", +] + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/crates/spin-sdk/test-cases/http-router/Cargo.toml b/crates/spin-sdk/test-cases/http-router/Cargo.toml new file mode 100644 index 0000000..ac082e2 --- /dev/null +++ b/crates/spin-sdk/test-cases/http-router/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "http-router" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +anyhow = "1.0.100" +bytes = "1.11.1" +http = "1.3.1" +http-body-util = "0.1.3" +spin-sdk = { path = "../..", features = ["router"] } + +[workspace] diff --git a/crates/spin-sdk/test-cases/http-router/src/lib.rs b/crates/spin-sdk/test-cases/http-router/src/lib.rs new file mode 100644 index 0000000..5eeda58 --- /dev/null +++ b/crates/spin-sdk/test-cases/http-router/src/lib.rs @@ -0,0 +1,57 @@ +use bytes::Bytes; +use http_body_util::BodyExt; +use spin_sdk::{ + http::{ + router::{Params, Router}, + FullBody, IntoResponse, Request, StatusCode, + }, + http_service, +}; + +fn reply(status: StatusCode, body: impl Into) -> impl IntoResponse { + (status, FullBody::new(body.into())) +} + +#[http_service] +async fn handle(req: Request) -> impl IntoResponse { + let mut router = Router::new(); + router.get("/hello/:name", hello); + router.post("/echo", echo); + router.get("/multiply/:x/:y", multiply); + router.get("/wild/*", wild); + router.any("/teapot", |_req: Request, _params: Params| async { + reply(StatusCode::IM_A_TEAPOT, "short and stout") + }); + router.put("/widgets/:id", update_widget); + router.handle(req).await +} + +async fn hello(_req: Request, params: Params) -> impl IntoResponse { + let name = params.get("name").unwrap_or("world").to_owned(); + reply(StatusCode::OK, format!("hello, {name}")) +} + +async fn echo(req: Request, _params: Params) -> impl IntoResponse { + let bytes = req + .into_body() + .collect() + .await + .map(|b| b.to_bytes()) + .unwrap_or_default(); + reply(StatusCode::OK, bytes) +} + +async fn multiply(_req: Request, params: Params) -> impl IntoResponse { + let x: i64 = params.get("x").and_then(|v| v.parse().ok()).unwrap_or(0); + let y: i64 = params.get("y").and_then(|v| v.parse().ok()).unwrap_or(0); + reply(StatusCode::OK, format!("{}", x * y)) +} + +async fn wild(_req: Request, params: Params) -> impl IntoResponse { + reply(StatusCode::OK, params.wildcard().unwrap_or("").to_owned()) +} + +async fn update_widget(_req: Request, params: Params) -> impl IntoResponse { + let id = params.get("id").unwrap_or("?").to_owned(); + reply(StatusCode::OK, format!("updated widget {id}")) +} diff --git a/crates/spin-sdk/test-cases/simple-http/Cargo.lock b/crates/spin-sdk/test-cases/simple-http/Cargo.lock index 977a7a8..262c8ef 100644 --- a/crates/spin-sdk/test-cases/simple-http/Cargo.lock +++ b/crates/spin-sdk/test-cases/simple-http/Cargo.lock @@ -37,9 +37,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bitflags" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" +checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" [[package]] name = "block-buffer" @@ -308,19 +308,13 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.16.1" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" dependencies = [ "foldhash 0.2.0", ] -[[package]] -name = "hashbrown" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" - [[package]] name = "heck" version = "0.5.0" @@ -704,7 +698,7 @@ dependencies = [ "spin-macro", "thiserror", "uuid", - "wasip3 0.5.0+wasi-0.3.0-rc-2026-03-15", + "wasip3 0.6.0+wasi-0.3.0-rc-2026-03-15", ] [[package]] @@ -844,14 +838,15 @@ dependencies = [ [[package]] name = "wasip3" -version = "0.5.0+wasi-0.3.0-rc-2026-03-15" -source = "git+https://github.com/bytecodealliance/wasi-rs#9d39023643c64a34f420beb2bca0aae950e29591" +version = "0.6.0+wasi-0.3.0-rc-2026-03-15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed83456dd6a0b8581998c0365e4651fa2997e5093b49243b7f35391afaa7a3d9" dependencies = [ "bytes", "http", "http-body", "thiserror", - "wit-bindgen 0.54.0", + "wit-bindgen 0.57.1", ] [[package]] @@ -911,12 +906,12 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.245.1" +version = "0.247.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9dca005e69bf015e45577e415b9af8c67e8ee3c0e38b5b0add5aa92581ed5c" +checksum = "30b6733b8b91d010a6ac5b0fb237dc46a19650bc4c67db66857e2e787d437204" dependencies = [ "leb128fmt", - "wasmparser 0.245.1", + "wasmparser 0.247.0", ] [[package]] @@ -933,14 +928,14 @@ dependencies = [ [[package]] name = "wasm-metadata" -version = "0.245.1" +version = "0.247.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da55e60097e8b37b475a0fa35c3420dd71d9eb7bd66109978ab55faf56a57efb" +checksum = "665fe59e56cc9b419ca6fcca56673e3421d1a5011e3b65caf6b726fd9e041d10" dependencies = [ "anyhow", "indexmap", - "wasm-encoder 0.245.1", - "wasmparser 0.245.1", + "wasm-encoder 0.247.0", + "wasmparser 0.247.0", ] [[package]] @@ -957,12 +952,12 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.245.1" +version = "0.247.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f08c9adee0428b7bddf3890fc27e015ac4b761cc608c822667102b8bfd6995e" +checksum = "8e6fb4c2bee46c5ea4d40f8cdb5c131725cd976718ec56f1c8e82fbde5fa2a80" dependencies = [ "bitflags", - "hashbrown 0.16.1", + "hashbrown 0.17.0", "indexmap", "semver", ] @@ -1037,12 +1032,13 @@ dependencies = [ [[package]] name = "wit-bindgen" -version = "0.54.0" +version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bb00254d5051d69730ee32580b7373592f10ad786757c372f0f2c7b61f86a2c" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" dependencies = [ + "bitflags", "futures", - "wit-bindgen-rust-macro 0.54.0", + "wit-bindgen-rust-macro 0.57.1", ] [[package]] @@ -1058,13 +1054,13 @@ dependencies = [ [[package]] name = "wit-bindgen-core" -version = "0.54.0" +version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99cdef5ccf0b0e9bf30868d6f9c5ed116c84ae95f84ba29d2216d3e922de3963" +checksum = "02dee27a2dc20d1008016c742ec9fc6ea498492994ba3750be7454cbc97ff04c" dependencies = [ "anyhow", "heck", - "wit-parser 0.245.1", + "wit-parser 0.247.0", ] [[package]] @@ -1085,18 +1081,18 @@ dependencies = [ [[package]] name = "wit-bindgen-rust" -version = "0.54.0" +version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e76541e2f37ac1729db85765729daa0f3c2b5975d66699114d107525f6d6c8d5" +checksum = "b5007dae772945b7a5003d69d90a3a4a78929d41f19d004e980c4259a6af4484" dependencies = [ "anyhow", "heck", "indexmap", "prettyplease", "syn 2.0.117", - "wasm-metadata 0.245.1", - "wit-bindgen-core 0.54.0", - "wit-component 0.245.1", + "wasm-metadata 0.247.0", + "wit-bindgen-core 0.57.1", + "wit-component 0.247.0", ] [[package]] @@ -1116,17 +1112,17 @@ dependencies = [ [[package]] name = "wit-bindgen-rust-macro" -version = "0.54.0" +version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a284e17b2bc808c72ba008f6694626fa76bcac608b3d1ed0880f9add3f558f8e" +checksum = "af9237d678e3513ad24e96fe98beacdc0db6405284ba2a2400418cf0d42caa89" dependencies = [ "anyhow", "prettyplease", "proc-macro2", "quote", "syn 2.0.117", - "wit-bindgen-core 0.54.0", - "wit-bindgen-rust 0.54.0", + "wit-bindgen-core 0.57.1", + "wit-bindgen-rust 0.57.1", ] [[package]] @@ -1150,9 +1146,9 @@ dependencies = [ [[package]] name = "wit-component" -version = "0.245.1" +version = "0.247.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4894f10d2d5cbc17c77e91f86a1e48e191a788da4425293b55c98b44ba3fcac9" +checksum = "9d567162a6b9843080e5e0053f696623ff694bae8ae017c9ec536d1873bbe3d8" dependencies = [ "anyhow", "bitflags", @@ -1161,10 +1157,10 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "wasm-encoder 0.245.1", - "wasm-metadata 0.245.1", - "wasmparser 0.245.1", - "wit-parser 0.245.1", + "wasm-encoder 0.247.0", + "wasm-metadata 0.247.0", + "wasmparser 0.247.0", + "wit-parser 0.247.0", ] [[package]] @@ -1187,12 +1183,12 @@ dependencies = [ [[package]] name = "wit-parser" -version = "0.245.1" +version = "0.247.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "330698718e82983499419494dd1e3d7811a457a9bf9f69734e8c5f07a2547929" +checksum = "8ffe4064318cdf3c08cb99343b44c039fcefe61ccdf58aa9975285f13d74d1fc" dependencies = [ "anyhow", - "hashbrown 0.16.1", + "hashbrown 0.17.0", "id-arena", "indexmap", "log", @@ -1201,7 +1197,7 @@ dependencies = [ "serde_derive", "serde_json", "unicode-xid", - "wasmparser 0.245.1", + "wasmparser 0.247.0", ] [[package]] diff --git a/crates/spin-sdk/test-cases/simple-redis/Cargo.lock b/crates/spin-sdk/test-cases/simple-redis/Cargo.lock index bb5b97b..d151351 100644 --- a/crates/spin-sdk/test-cases/simple-redis/Cargo.lock +++ b/crates/spin-sdk/test-cases/simple-redis/Cargo.lock @@ -37,9 +37,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bitflags" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" +checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" [[package]] name = "block-buffer" @@ -308,19 +308,13 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.16.1" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" dependencies = [ "foldhash 0.2.0", ] -[[package]] -name = "hashbrown" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" - [[package]] name = "heck" version = "0.5.0" @@ -704,7 +698,7 @@ dependencies = [ "spin-macro", "thiserror", "uuid", - "wasip3 0.5.0+wasi-0.3.0-rc-2026-03-15", + "wasip3 0.6.0+wasi-0.3.0-rc-2026-03-15", ] [[package]] @@ -844,14 +838,15 @@ dependencies = [ [[package]] name = "wasip3" -version = "0.5.0+wasi-0.3.0-rc-2026-03-15" -source = "git+https://github.com/bytecodealliance/wasi-rs#9d39023643c64a34f420beb2bca0aae950e29591" +version = "0.6.0+wasi-0.3.0-rc-2026-03-15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed83456dd6a0b8581998c0365e4651fa2997e5093b49243b7f35391afaa7a3d9" dependencies = [ "bytes", "http", "http-body", "thiserror", - "wit-bindgen 0.54.0", + "wit-bindgen 0.57.1", ] [[package]] @@ -911,12 +906,12 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.245.1" +version = "0.247.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9dca005e69bf015e45577e415b9af8c67e8ee3c0e38b5b0add5aa92581ed5c" +checksum = "30b6733b8b91d010a6ac5b0fb237dc46a19650bc4c67db66857e2e787d437204" dependencies = [ "leb128fmt", - "wasmparser 0.245.1", + "wasmparser 0.247.0", ] [[package]] @@ -933,14 +928,14 @@ dependencies = [ [[package]] name = "wasm-metadata" -version = "0.245.1" +version = "0.247.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da55e60097e8b37b475a0fa35c3420dd71d9eb7bd66109978ab55faf56a57efb" +checksum = "665fe59e56cc9b419ca6fcca56673e3421d1a5011e3b65caf6b726fd9e041d10" dependencies = [ "anyhow", "indexmap", - "wasm-encoder 0.245.1", - "wasmparser 0.245.1", + "wasm-encoder 0.247.0", + "wasmparser 0.247.0", ] [[package]] @@ -957,12 +952,12 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.245.1" +version = "0.247.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f08c9adee0428b7bddf3890fc27e015ac4b761cc608c822667102b8bfd6995e" +checksum = "8e6fb4c2bee46c5ea4d40f8cdb5c131725cd976718ec56f1c8e82fbde5fa2a80" dependencies = [ "bitflags", - "hashbrown 0.16.1", + "hashbrown 0.17.0", "indexmap", "semver", ] @@ -1037,12 +1032,13 @@ dependencies = [ [[package]] name = "wit-bindgen" -version = "0.54.0" +version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bb00254d5051d69730ee32580b7373592f10ad786757c372f0f2c7b61f86a2c" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" dependencies = [ + "bitflags", "futures", - "wit-bindgen-rust-macro 0.54.0", + "wit-bindgen-rust-macro 0.57.1", ] [[package]] @@ -1058,13 +1054,13 @@ dependencies = [ [[package]] name = "wit-bindgen-core" -version = "0.54.0" +version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99cdef5ccf0b0e9bf30868d6f9c5ed116c84ae95f84ba29d2216d3e922de3963" +checksum = "02dee27a2dc20d1008016c742ec9fc6ea498492994ba3750be7454cbc97ff04c" dependencies = [ "anyhow", "heck", - "wit-parser 0.245.1", + "wit-parser 0.247.0", ] [[package]] @@ -1085,18 +1081,18 @@ dependencies = [ [[package]] name = "wit-bindgen-rust" -version = "0.54.0" +version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e76541e2f37ac1729db85765729daa0f3c2b5975d66699114d107525f6d6c8d5" +checksum = "b5007dae772945b7a5003d69d90a3a4a78929d41f19d004e980c4259a6af4484" dependencies = [ "anyhow", "heck", "indexmap", "prettyplease", "syn 2.0.117", - "wasm-metadata 0.245.1", - "wit-bindgen-core 0.54.0", - "wit-component 0.245.1", + "wasm-metadata 0.247.0", + "wit-bindgen-core 0.57.1", + "wit-component 0.247.0", ] [[package]] @@ -1116,17 +1112,17 @@ dependencies = [ [[package]] name = "wit-bindgen-rust-macro" -version = "0.54.0" +version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a284e17b2bc808c72ba008f6694626fa76bcac608b3d1ed0880f9add3f558f8e" +checksum = "af9237d678e3513ad24e96fe98beacdc0db6405284ba2a2400418cf0d42caa89" dependencies = [ "anyhow", "prettyplease", "proc-macro2", "quote", "syn 2.0.117", - "wit-bindgen-core 0.54.0", - "wit-bindgen-rust 0.54.0", + "wit-bindgen-core 0.57.1", + "wit-bindgen-rust 0.57.1", ] [[package]] @@ -1150,9 +1146,9 @@ dependencies = [ [[package]] name = "wit-component" -version = "0.245.1" +version = "0.247.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4894f10d2d5cbc17c77e91f86a1e48e191a788da4425293b55c98b44ba3fcac9" +checksum = "9d567162a6b9843080e5e0053f696623ff694bae8ae017c9ec536d1873bbe3d8" dependencies = [ "anyhow", "bitflags", @@ -1161,10 +1157,10 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "wasm-encoder 0.245.1", - "wasm-metadata 0.245.1", - "wasmparser 0.245.1", - "wit-parser 0.245.1", + "wasm-encoder 0.247.0", + "wasm-metadata 0.247.0", + "wasmparser 0.247.0", + "wit-parser 0.247.0", ] [[package]] @@ -1187,12 +1183,12 @@ dependencies = [ [[package]] name = "wit-parser" -version = "0.245.1" +version = "0.247.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "330698718e82983499419494dd1e3d7811a457a9bf9f69734e8c5f07a2547929" +checksum = "8ffe4064318cdf3c08cb99343b44c039fcefe61ccdf58aa9975285f13d74d1fc" dependencies = [ "anyhow", - "hashbrown 0.16.1", + "hashbrown 0.17.0", "id-arena", "indexmap", "log", @@ -1201,7 +1197,7 @@ dependencies = [ "serde_derive", "serde_json", "unicode-xid", - "wasmparser 0.245.1", + "wasmparser 0.247.0", ] [[package]]