wasmcloud_control_interface/lib.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
//! # Control Interface Client
//!
//! This library provides a client API for consuming the [wasmCloud control interface][docs-control-interface]
//! over a NATS connection.
//!
//! This library can be used by multiple types of tools, and is also used
//! by the control interface capability provider and the [`wash` CLI][wash-cli].
//!
//! ## Usage
//!
//! All of the [`Client`] functions are handled by a wasmCloud host running in the specified lattice.
//!
//! Each function returns a `Result<CtlResponse<T>>` wrapper around the actual response type. The outer
//! result should be handled for protocol (timeouts, no hosts available) and deserialization errors (invalid response payload).
//! The inner result is the actual response from the host(s) and should be handled for application-level errors.
//!
//! [docs-control-interface]: <https://wasmcloud.com/docs/hosts/lattice-protocols/control-interface>
//! [wash-cli]: <https://wasmcloud.com/docs/ecosystem/wash>
use serde::{Deserialize, Serialize};
mod broker;
mod otel;
pub mod client;
pub use client::{Client, ClientBuilder};
mod types;
pub use types::component::*;
pub use types::ctl::*;
pub use types::host::*;
pub use types::link::*;
pub use types::provider::*;
pub use types::registry::*;
pub use types::rpc::*;
// NOTE(brooksmtownsend): These are included to avoid a major breaking change
// in this crate by removing the public type aliases. They should be removed
// when we release 3.0.0 of this crate.
#[deprecated(
since = "2.3.0",
note = "String type aliases are deprecated, use Strings instead"
)]
#[allow(dead_code)]
mod aliases {
type ComponentId = String;
type KnownConfigName = String;
type LatticeTarget = String;
type LinkName = String;
type WitInterface = String;
type WitNamespace = String;
type WitPackage = String;
}
#[allow(unused_imports)]
#[allow(deprecated)]
pub use aliases::*;
/// Generic result
type Result<T> = ::core::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
/// Enumeration of all kinds of identifiers in a wasmCloud lattice
#[allow(unused)]
pub(crate) enum IdentifierKind {
/// Identifiers that are host IDs
HostId,
/// Identifiers that are component IDs
ComponentId,
/// Identifiers that are component references
ComponentRefs,
/// Identifiers that are provider reverences
ProviderRef,
/// Identifiers that are link names
LinkName,
}
impl IdentifierKind {
/// Ensure an identifier is a valid as a host ID
fn is_host_id(value: impl AsRef<str>) -> Result<String> {
assert_non_empty_string(value, "Host ID cannot be empty")
}
/// Ensure an identifier is a valid as a component ID
fn is_component_id(value: impl AsRef<str>) -> Result<String> {
assert_non_empty_string(value, "Component ID cannot be empty")
}
/// Ensure an identifier is a valid as a component reference
fn is_component_ref(value: impl AsRef<str>) -> Result<String> {
assert_non_empty_string(value, "Component OCI reference cannot be empty")
}
/// Ensure an identifier is a valid as a provider reference
fn is_provider_ref(value: impl AsRef<str>) -> Result<String> {
assert_non_empty_string(value, "Provider OCI reference cannot be empty")
}
/// Ensure an identifier is a valid as a provider reference
fn is_provider_id(value: impl AsRef<str>) -> Result<String> {
assert_non_empty_string(value, "Provider ID cannot be empty")
}
/// Ensure an identifier is a valid as a link name
fn is_link_name(value: impl AsRef<str>) -> Result<String> {
assert_non_empty_string(value, "Link Name cannot be empty")
}
}
/// Helper function that serializes the data and maps the error
pub(crate) fn json_serialize<T>(item: T) -> Result<Vec<u8>>
where
T: Serialize,
{
serde_json::to_vec(&item).map_err(|e| format!("JSON serialization failure: {e}").into())
}
/// Helper function that deserializes the data and maps the error
pub(crate) fn json_deserialize<'de, T: Deserialize<'de>>(buf: &'de [u8]) -> Result<T> {
serde_json::from_slice(buf).map_err(|e| format!("JSON deserialization failure: {e}").into())
}
/// Check that a likely user-provided string is non empty
fn assert_non_empty_string(input: impl AsRef<str>, message: impl AsRef<str>) -> Result<String> {
let input = input.as_ref();
let message = message.as_ref();
if input.trim().is_empty() {
Err(message.into())
} else {
Ok(input.trim().to_string())
}
}