// Code generated by ndpgen. DO NOT EDIT. // // This file contains client wrappers for the KVStore host service. // It is intended for use in Navidrome plugins built with extism-pdk. use extism_pdk::*; use serde::{Deserialize, Serialize}; use base64::Engine as _; use base64::engine::general_purpose::STANDARD as BASE64; mod base64_bytes { use serde::{self, Deserialize, Deserializer, Serializer}; use base64::Engine as _; use base64::engine::general_purpose::STANDARD as BASE64; pub fn serialize(bytes: &Vec, serializer: S) -> Result where S: Serializer, { serializer.serialize_str(&BASE64.encode(bytes)) } pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { let s = String::deserialize(deserializer)?; BASE64.decode(&s).map_err(serde::de::Error::custom) } } #[derive(Debug, Clone, Serialize)] #[serde(rename_all = "camelCase")] struct KVStoreSetRequest { key: String, #[serde(with = "base64_bytes")] value: Vec, } #[derive(Debug, Clone, Deserialize)] #[serde(rename_all = "camelCase")] struct KVStoreSetResponse { #[serde(default)] error: Option, } #[derive(Debug, Clone, Serialize)] #[serde(rename_all = "camelCase")] struct KVStoreSetWithTTLRequest { key: String, #[serde(with = "base64_bytes")] value: Vec, ttl_seconds: i64, } #[derive(Debug, Clone, Deserialize)] #[serde(rename_all = "camelCase")] struct KVStoreSetWithTTLResponse { #[serde(default)] error: Option, } #[derive(Debug, Clone, Serialize)] #[serde(rename_all = "camelCase")] struct KVStoreGetRequest { key: String, } #[derive(Debug, Clone, Deserialize)] #[serde(rename_all = "camelCase")] struct KVStoreGetResponse { #[serde(default)] #[serde(with = "base64_bytes")] value: Vec, #[serde(default)] exists: bool, #[serde(default)] error: Option, } #[derive(Debug, Clone, Serialize)] #[serde(rename_all = "camelCase")] struct KVStoreGetManyRequest { keys: Vec, } #[derive(Debug, Clone, Deserialize)] #[serde(rename_all = "camelCase")] struct KVStoreGetManyResponse { #[serde(default)] values: std::collections::HashMap>, #[serde(default)] error: Option, } #[derive(Debug, Clone, Serialize)] #[serde(rename_all = "camelCase")] struct KVStoreHasRequest { key: String, } #[derive(Debug, Clone, Deserialize)] #[serde(rename_all = "camelCase")] struct KVStoreHasResponse { #[serde(default)] exists: bool, #[serde(default)] error: Option, } #[derive(Debug, Clone, Serialize)] #[serde(rename_all = "camelCase")] struct KVStoreListRequest { prefix: String, } #[derive(Debug, Clone, Deserialize)] #[serde(rename_all = "camelCase")] struct KVStoreListResponse { #[serde(default)] keys: Vec, #[serde(default)] error: Option, } #[derive(Debug, Clone, Serialize)] #[serde(rename_all = "camelCase")] struct KVStoreDeleteRequest { key: String, } #[derive(Debug, Clone, Deserialize)] #[serde(rename_all = "camelCase")] struct KVStoreDeleteResponse { #[serde(default)] error: Option, } #[derive(Debug, Clone, Serialize)] #[serde(rename_all = "camelCase")] struct KVStoreDeleteByPrefixRequest { prefix: String, } #[derive(Debug, Clone, Deserialize)] #[serde(rename_all = "camelCase")] struct KVStoreDeleteByPrefixResponse { #[serde(default)] deleted_count: i64, #[serde(default)] error: Option, } #[derive(Debug, Clone, Deserialize)] #[serde(rename_all = "camelCase")] struct KVStoreGetStorageUsedResponse { #[serde(default)] bytes: i64, #[serde(default)] error: Option, } #[host_fn] extern "ExtismHost" { fn kvstore_set(input: Json) -> Json; fn kvstore_setwithttl(input: Json) -> Json; fn kvstore_get(input: Json) -> Json; fn kvstore_getmany(input: Json) -> Json; fn kvstore_has(input: Json) -> Json; fn kvstore_list(input: Json) -> Json; fn kvstore_delete(input: Json) -> Json; fn kvstore_deletebyprefix(input: Json) -> Json; fn kvstore_getstorageused(input: Json) -> Json; } /// Set stores a byte value with the given key. /// /// Parameters: /// - key: The storage key (max 256 bytes, UTF-8) /// - value: The byte slice to store /// /// Returns an error if the storage limit would be exceeded or the operation fails. /// /// # Arguments /// * `key` - String parameter. /// * `value` - Vec parameter. /// /// # Errors /// Returns an error if the host function call fails. pub fn set(key: &str, value: Vec) -> Result<(), Error> { let response = unsafe { kvstore_set(Json(KVStoreSetRequest { key: key.to_owned(), value: value, }))? }; if let Some(err) = response.0.error { return Err(Error::msg(err)); } Ok(()) } /// SetWithTTL stores a byte value with the given key and a time-to-live. /// /// After ttlSeconds, the key is treated as non-existent and will be /// cleaned up lazily. ttlSeconds must be greater than 0. /// /// Parameters: /// - key: The storage key (max 256 bytes, UTF-8) /// - value: The byte slice to store /// - ttlSeconds: Time-to-live in seconds (must be > 0) /// /// Returns an error if the storage limit would be exceeded or the operation fails. /// /// # Arguments /// * `key` - String parameter. /// * `value` - Vec parameter. /// * `ttl_seconds` - i64 parameter. /// /// # Errors /// Returns an error if the host function call fails. pub fn set_with_ttl(key: &str, value: Vec, ttl_seconds: i64) -> Result<(), Error> { let response = unsafe { kvstore_setwithttl(Json(KVStoreSetWithTTLRequest { key: key.to_owned(), value: value, ttl_seconds: ttl_seconds, }))? }; if let Some(err) = response.0.error { return Err(Error::msg(err)); } Ok(()) } /// Get retrieves a byte value from storage. /// /// Parameters: /// - key: The storage key /// /// Returns the value and whether the key exists. /// /// # Arguments /// * `key` - String parameter. /// /// # Returns /// `Some(value)` if found, `None` otherwise. /// /// # Errors /// Returns an error if the host function call fails. pub fn get(key: &str) -> Result>, Error> { let response = unsafe { kvstore_get(Json(KVStoreGetRequest { key: key.to_owned(), }))? }; if let Some(err) = response.0.error { return Err(Error::msg(err)); } if response.0.exists { Ok(Some(response.0.value)) } else { Ok(None) } } /// GetMany retrieves multiple values in a single call. /// /// Parameters: /// - keys: The storage keys to retrieve /// /// Returns a map of key to value for keys that exist and have not expired. /// Missing or expired keys are omitted from the result. /// /// # Arguments /// * `keys` - Vec parameter. /// /// # Returns /// The values value. /// /// # Errors /// Returns an error if the host function call fails. pub fn get_many(keys: Vec) -> Result>, Error> { let response = unsafe { kvstore_getmany(Json(KVStoreGetManyRequest { keys: keys, }))? }; if let Some(err) = response.0.error { return Err(Error::msg(err)); } Ok(response.0.values) } /// Has checks if a key exists in storage. /// /// Parameters: /// - key: The storage key /// /// Returns true if the key exists. /// /// # Arguments /// * `key` - String parameter. /// /// # Returns /// The exists value. /// /// # Errors /// Returns an error if the host function call fails. pub fn has(key: &str) -> Result { let response = unsafe { kvstore_has(Json(KVStoreHasRequest { key: key.to_owned(), }))? }; if let Some(err) = response.0.error { return Err(Error::msg(err)); } Ok(response.0.exists) } /// List returns all keys matching the given prefix. /// /// Parameters: /// - prefix: Key prefix to filter by (empty string returns all keys) /// /// Returns a slice of matching keys. /// /// # Arguments /// * `prefix` - String parameter. /// /// # Returns /// The keys value. /// /// # Errors /// Returns an error if the host function call fails. pub fn list(prefix: &str) -> Result, Error> { let response = unsafe { kvstore_list(Json(KVStoreListRequest { prefix: prefix.to_owned(), }))? }; if let Some(err) = response.0.error { return Err(Error::msg(err)); } Ok(response.0.keys) } /// Delete removes a value from storage. /// /// Parameters: /// - key: The storage key /// /// Returns an error if the operation fails. Does not return an error if the key doesn't exist. /// /// # Arguments /// * `key` - String parameter. /// /// # Errors /// Returns an error if the host function call fails. pub fn delete(key: &str) -> Result<(), Error> { let response = unsafe { kvstore_delete(Json(KVStoreDeleteRequest { key: key.to_owned(), }))? }; if let Some(err) = response.0.error { return Err(Error::msg(err)); } Ok(()) } /// DeleteByPrefix removes all keys matching the given prefix. /// /// Parameters: /// - prefix: Key prefix to match (must not be empty) /// /// Returns the number of keys deleted. Includes expired keys. /// /// # Arguments /// * `prefix` - String parameter. /// /// # Returns /// The deleted_count value. /// /// # Errors /// Returns an error if the host function call fails. pub fn delete_by_prefix(prefix: &str) -> Result { let response = unsafe { kvstore_deletebyprefix(Json(KVStoreDeleteByPrefixRequest { prefix: prefix.to_owned(), }))? }; if let Some(err) = response.0.error { return Err(Error::msg(err)); } Ok(response.0.deleted_count) } /// GetStorageUsed returns the total storage used by this plugin in bytes. /// /// # Returns /// The bytes value. /// /// # Errors /// Returns an error if the host function call fails. pub fn get_storage_used() -> Result { let response = unsafe { kvstore_getstorageused(Json(serde_json::json!({})))? }; if let Some(err) = response.0.error { return Err(Error::msg(err)); } Ok(response.0.bytes) }