feat(component): add KV capability probe
Add a small Component that imports wasmeld:kv/store@0.1.0 and exercises get, set, and delete through a byte-oriented test protocol. Pin service and KV WIT dependencies in wit.lock while keeping generated wit/deps content out of source control.
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
[package]
|
||||
name = "kv-probe-component"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
[package.metadata.wasmeld]
|
||||
id = "kv-probe"
|
||||
world = "component:kv-probe/kv-probe-component@0.1.0"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
wit-bindgen.workspace = true
|
||||
@@ -0,0 +1,63 @@
|
||||
mod bindings {
|
||||
wit_bindgen::generate!({
|
||||
path: "wit",
|
||||
world: "kv-probe-component",
|
||||
generate_all,
|
||||
});
|
||||
}
|
||||
|
||||
use bindings::wasmeld::kv::store;
|
||||
|
||||
struct KvProbe;
|
||||
|
||||
impl bindings::Guest for KvProbe {
|
||||
fn init(_config: Vec<u8>) -> Result<(), bindings::ServiceError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn invoke(input: Vec<u8>) -> Result<Vec<u8>, bindings::ServiceError> {
|
||||
if let Some(key) = input.strip_prefix(b"get:") {
|
||||
let key = parse_key(key)?;
|
||||
return store::get(&key)
|
||||
.map(|value| value.unwrap_or_default())
|
||||
.map_err(kv_error);
|
||||
}
|
||||
|
||||
if let Some(command) = input.strip_prefix(b"set:") {
|
||||
let separator = command
|
||||
.iter()
|
||||
.position(|byte| *byte == b':')
|
||||
.ok_or_else(|| {
|
||||
bindings::ServiceError::CallFailed(
|
||||
"set command must be set:<key>:<value>".to_owned(),
|
||||
)
|
||||
})?;
|
||||
let key = parse_key(&command[..separator])?;
|
||||
let value = command[separator + 1..].to_vec();
|
||||
store::set(&key, &value).map_err(kv_error)?;
|
||||
return Ok(Vec::new());
|
||||
}
|
||||
|
||||
if let Some(key) = input.strip_prefix(b"delete:") {
|
||||
let key = parse_key(key)?;
|
||||
store::delete(&key).map_err(kv_error)?;
|
||||
return Ok(Vec::new());
|
||||
}
|
||||
|
||||
Err(bindings::ServiceError::CallFailed(
|
||||
"expected get:<key>, set:<key>:<value>, or delete:<key>".to_owned(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_key(bytes: &[u8]) -> Result<String, bindings::ServiceError> {
|
||||
core::str::from_utf8(bytes)
|
||||
.map(str::to_owned)
|
||||
.map_err(|_| bindings::ServiceError::CallFailed("key must be valid UTF-8".to_owned()))
|
||||
}
|
||||
|
||||
fn kv_error(error: store::KvError) -> bindings::ServiceError {
|
||||
bindings::ServiceError::CallFailed(format!("KV operation failed: {error:?}"))
|
||||
}
|
||||
|
||||
bindings::export!(KvProbe with_types_in bindings);
|
||||
@@ -0,0 +1,11 @@
|
||||
schema_version = 1
|
||||
|
||||
[dependencies]
|
||||
"wasmeld:kv" = "0.1.0"
|
||||
"wasmeld:service" = "0.1.0"
|
||||
|
||||
[replace."wasmeld:kv"]
|
||||
path = "../../wit/kv"
|
||||
|
||||
[replace."wasmeld:service"]
|
||||
path = "../../wit/service"
|
||||
@@ -0,0 +1,15 @@
|
||||
schema_version = 1
|
||||
|
||||
[[package]]
|
||||
name = "wasmeld:kv"
|
||||
version = "0.1.0"
|
||||
source = "path+../../wit/kv"
|
||||
sha256 = "6dc3a84dc03c7104aa8b305518466c95e4440e1031c4bef3b59843f40f24d0fb"
|
||||
replaced = true
|
||||
|
||||
[[package]]
|
||||
name = "wasmeld:service"
|
||||
version = "0.1.0"
|
||||
source = "path+../../wit/service"
|
||||
sha256 = "d5497307bbcd1e159f7707f385b488a6f2e26362d5256d5bc1080ac603a51305"
|
||||
replaced = true
|
||||
@@ -0,0 +1,6 @@
|
||||
package component:kv-probe@0.1.0;
|
||||
|
||||
world kv-probe-component {
|
||||
include wasmeld:service/service-component@0.1.0;
|
||||
import wasmeld:kv/store@0.1.0;
|
||||
}
|
||||
Reference in New Issue
Block a user