mod decode;
mod encode;
#[cfg(all(feature = "guest", not(feature = "host")))]
pub mod direct;
#[cfg(any(
all(feature = "guest", not(feature = "host")),
all(feature = "host", not(feature = "guest"))
))]
mod model;
#[cfg(all(feature = "guest", not(feature = "host")))]
pub(crate) mod guest;
#[cfg(all(feature = "host", not(feature = "guest")))]
pub(crate) mod host;
#[cfg(all(feature = "guest", not(feature = "host")))]
pub use guest::generated::golem::core::types as wire;
#[cfg(all(feature = "host", not(feature = "guest")))]
pub use host::generated::golem::core::types as wire;
pub(crate) use decode::decode_value_by_ref;
pub use decode::{
DecodeError, GraphDecoder, decode_graph, decode_metadata, decode_typed, decode_value,
};
pub use encode::{
EncodeError, GraphEncoder, encode_graph, encode_metadata, encode_typed, encode_value,
};
#[cfg(all(feature = "guest", not(feature = "host")))]
pub use encode::{encode_typed_async, encode_value_async};
#[cfg(all(feature = "guest", not(feature = "host")))]
pub use decode::decode_typed_owned;
#[cfg(all(feature = "guest", not(feature = "host")))]
pub use encode::encode_typed_owned;
#[cfg(all(feature = "host", not(feature = "guest")))]
pub use decode::{
decode_typed_rejecting_permission_card_with, decode_typed_rejecting_quota_with,
decode_typed_rejecting_secret_with, decode_value_rejecting_permission_card_with,
decode_value_rejecting_quota_with, decode_value_rejecting_secret_with, decode_value_with,
reject_permission_card_handles_in_value_tree, reject_quota_handles_in_value_tree,
reject_secret_handles_in_value_tree,
};
#[cfg(all(feature = "host", not(feature = "guest")))]
pub use encode::{encode_value_with, encode_value_with_streams};
#[cfg(all(feature = "host", not(feature = "guest")))]
pub use host_support::{
PermissionCardHandleDropper, PermissionCardHandleRep, PermissionCardResolver,
QuotaTokenHandleDropper, QuotaTokenHandleRep, QuotaTokenResolver, SchemaValueStreamResolver,
SecretHandleDropper, SecretHandleRep, SecretResolver,
};
#[cfg(all(feature = "guest", not(feature = "host")))]
pub use guest_support::{GuestPermissionCardHandle, GuestQuotaTokenHandle, GuestSecretHandle};
#[cfg(all(feature = "guest", not(feature = "host")))]
pub fn new_schema_value_stream() -> (
wit_bindgen::StreamWriter<wire::SchemaValueTree>,
wit_bindgen::StreamReader<wire::SchemaValueTree>,
) {
guest::generated::wit_stream::new()
}
#[cfg(all(feature = "host", not(feature = "guest")))]
mod host_support {
use crate::schema::schema_value::{
PermissionCardValuePayload, QuotaTokenValuePayload, SecretValuePayload,
};
use crate::schema::{SchemaValueStream, SchemaValueStreamHandleRep};
use wasmtime::component::Resource;
pub trait SchemaValueStreamResolver {
type Error: std::fmt::Display;
fn handle_from_stream(
&mut self,
stream: SchemaValueStream,
) -> Result<Resource<SchemaValueStreamHandleRep>, Self::Error>;
fn stream_from_handle(
&mut self,
handle: Resource<SchemaValueStreamHandleRep>,
) -> Result<SchemaValueStream, Self::Error>;
fn drop_stream_handle(&mut self, handle: Resource<SchemaValueStreamHandleRep>);
}
pub struct QuotaTokenHandleRep {
payload: Box<dyn std::any::Any + Send + Sync>,
}
impl QuotaTokenHandleRep {
pub fn new(payload: impl std::any::Any + Send + Sync) -> Self {
Self {
payload: Box::new(payload),
}
}
pub fn downcast_ref<T: std::any::Any>(&self) -> Option<&T> {
self.payload.downcast_ref::<T>()
}
pub fn downcast_mut<T: std::any::Any>(&mut self) -> Option<&mut T> {
self.payload.downcast_mut::<T>()
}
pub fn into_payload<T: std::any::Any>(self) -> Result<T, Self> {
match self.payload.downcast::<T>() {
Ok(boxed) => Ok(*boxed),
Err(payload) => Err(Self { payload }),
}
}
}
pub trait QuotaTokenResolver {
type Error: std::fmt::Display;
fn snapshot_handle(
&mut self,
handle: Resource<QuotaTokenHandleRep>,
) -> Result<QuotaTokenValuePayload, Self::Error>;
fn handle_from_snapshot(
&mut self,
snapshot: &QuotaTokenValuePayload,
) -> Result<Resource<QuotaTokenHandleRep>, Self::Error>;
fn drop_handle(&mut self, handle: Resource<QuotaTokenHandleRep>);
}
pub trait SecretResolver {
type Error: std::fmt::Display;
fn snapshot_secret_handle(
&mut self,
handle: Resource<SecretHandleRep>,
) -> Result<SecretValuePayload, Self::Error>;
fn secret_handle_from_snapshot(
&mut self,
snapshot: &SecretValuePayload,
) -> Result<Resource<SecretHandleRep>, Self::Error>;
fn drop_secret_handle(&mut self, handle: Resource<SecretHandleRep>);
}
pub trait QuotaTokenHandleDropper {
fn drop_quota_token_handle(&mut self, handle: Resource<QuotaTokenHandleRep>);
}
pub trait SecretHandleDropper {
fn drop_secret_handle(&mut self, handle: Resource<SecretHandleRep>);
}
impl<R: QuotaTokenResolver> QuotaTokenHandleDropper for R {
fn drop_quota_token_handle(&mut self, handle: Resource<QuotaTokenHandleRep>) {
QuotaTokenResolver::drop_handle(self, handle)
}
}
impl<R: SecretResolver> SecretHandleDropper for R {
fn drop_secret_handle(&mut self, handle: Resource<SecretHandleRep>) {
SecretResolver::drop_secret_handle(self, handle)
}
}
pub struct SecretHandleRep {
payload: Box<dyn std::any::Any + Send + Sync>,
}
impl SecretHandleRep {
pub fn new(payload: impl std::any::Any + Send + Sync) -> Self {
Self {
payload: Box::new(payload),
}
}
pub fn downcast_ref<T: std::any::Any>(&self) -> Option<&T> {
self.payload.downcast_ref::<T>()
}
pub fn downcast_mut<T: std::any::Any>(&mut self) -> Option<&mut T> {
self.payload.downcast_mut::<T>()
}
pub fn into_payload<T: std::any::Any>(self) -> Result<T, Self> {
match self.payload.downcast::<T>() {
Ok(boxed) => Ok(*boxed),
Err(payload) => Err(Self { payload }),
}
}
}
pub struct PermissionCardHandleRep {
payload: Box<dyn std::any::Any + Send + Sync>,
}
impl PermissionCardHandleRep {
pub fn new(payload: impl std::any::Any + Send + Sync) -> Self {
Self {
payload: Box::new(payload),
}
}
pub fn downcast_ref<T: std::any::Any>(&self) -> Option<&T> {
self.payload.downcast_ref::<T>()
}
pub fn downcast_mut<T: std::any::Any>(&mut self) -> Option<&mut T> {
self.payload.downcast_mut::<T>()
}
pub fn into_payload<T: std::any::Any>(self) -> Result<T, Self> {
match self.payload.downcast::<T>() {
Ok(boxed) => Ok(*boxed),
Err(payload) => Err(Self { payload }),
}
}
}
pub trait PermissionCardResolver {
type Error: std::fmt::Display;
fn snapshot_permission_card_handle(
&mut self,
handle: Resource<PermissionCardHandleRep>,
) -> Result<PermissionCardValuePayload, Self::Error>;
fn permission_card_handle_from_snapshot(
&mut self,
snapshot: &PermissionCardValuePayload,
) -> Result<Resource<PermissionCardHandleRep>, Self::Error>;
fn drop_permission_card_handle(&mut self, handle: Resource<PermissionCardHandleRep>);
}
pub trait PermissionCardHandleDropper {
fn drop_permission_card_handle(&mut self, handle: Resource<PermissionCardHandleRep>);
}
impl<R: PermissionCardResolver> PermissionCardHandleDropper for R {
fn drop_permission_card_handle(&mut self, handle: Resource<PermissionCardHandleRep>) {
PermissionCardResolver::drop_permission_card_handle(self, handle)
}
}
}
#[cfg(all(feature = "guest", not(feature = "host")))]
mod guest_support {
use super::wire;
use crate::schema::conversion::{FromSchema, FromSchemaError, IntoSchema, SchemaBuilder};
use crate::schema::metadata::TypeId;
use crate::schema::schema_type::{PermissionCardSpec, QuotaTokenSpec, SchemaType};
use crate::schema::schema_value::SchemaValue;
use std::sync::{Arc, Mutex};
#[derive(Clone)]
pub struct GuestQuotaTokenHandle {
inner: Arc<Mutex<Option<wire::QuotaToken>>>,
}
impl GuestQuotaTokenHandle {
#[doc(hidden)]
pub fn new(handle: wire::QuotaToken) -> Self {
Self {
inner: Arc::new(Mutex::new(Some(handle))),
}
}
#[doc(hidden)]
pub fn take(&self) -> Option<wire::QuotaToken> {
self.inner
.lock()
.unwrap_or_else(|poison| poison.into_inner())
.take()
}
#[doc(hidden)]
pub fn is_present(&self) -> bool {
self.inner
.lock()
.unwrap_or_else(|poison| poison.into_inner())
.is_some()
}
#[doc(hidden)]
pub fn with_handle<R>(&self, f: impl FnOnce(&wire::QuotaToken) -> R) -> Option<R> {
self.inner
.lock()
.unwrap_or_else(|poison| poison.into_inner())
.as_ref()
.map(f)
}
#[doc(hidden)]
pub fn cell_id(&self) -> *const () {
Arc::as_ptr(&self.inner).cast()
}
}
impl std::fmt::Debug for GuestQuotaTokenHandle {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let state = if self.is_present() {
"present"
} else {
"consumed"
};
write!(f, "GuestQuotaTokenHandle(<{state}>)")
}
}
impl PartialEq for GuestQuotaTokenHandle {
fn eq(&self, other: &Self) -> bool {
Arc::ptr_eq(&self.inner, &other.inner)
}
}
impl serde::Serialize for GuestQuotaTokenHandle {
fn serialize<S: serde::Serializer>(&self, _serializer: S) -> Result<S::Ok, S::Error> {
Err(serde::ser::Error::custom(
"quota-token handles cannot be serialized; transfer them through a WIT schema-value-tree",
))
}
}
impl<'de> serde::Deserialize<'de> for GuestQuotaTokenHandle {
fn deserialize<D: serde::Deserializer<'de>>(_deserializer: D) -> Result<Self, D::Error> {
Err(serde::de::Error::custom(
"quota-token handles cannot be deserialized or forged from data",
))
}
}
impl IntoSchema for GuestQuotaTokenHandle {
fn type_id() -> TypeId {
TypeId::new("golem.core.QuotaToken")
}
fn register_in(_builder: &mut SchemaBuilder) -> SchemaType {
SchemaType::quota_token(QuotaTokenSpec::default())
}
fn to_value(&self) -> SchemaValue {
SchemaValue::QuotaToken(self.clone())
}
}
impl FromSchema for GuestQuotaTokenHandle {
fn from_value(value: &SchemaValue) -> Result<Self, FromSchemaError> {
match value {
SchemaValue::QuotaToken(h) => Ok(h.clone()),
other => Err(FromSchemaError::shape_mismatch(
"quota-token",
format!("{other:?}"),
"QuotaToken",
)),
}
}
}
#[derive(Clone)]
pub struct GuestSecretHandle {
inner: Arc<Mutex<Option<wire::Secret>>>,
}
impl GuestSecretHandle {
#[doc(hidden)]
pub fn new(handle: wire::Secret) -> Self {
Self {
inner: Arc::new(Mutex::new(Some(handle))),
}
}
#[doc(hidden)]
pub fn take(&self) -> Option<wire::Secret> {
self.inner
.lock()
.unwrap_or_else(|poison| poison.into_inner())
.take()
}
#[doc(hidden)]
pub fn is_present(&self) -> bool {
self.inner
.lock()
.unwrap_or_else(|poison| poison.into_inner())
.is_some()
}
#[doc(hidden)]
pub fn with_handle<R>(&self, f: impl FnOnce(&wire::Secret) -> R) -> Option<R> {
self.inner
.lock()
.unwrap_or_else(|poison| poison.into_inner())
.as_ref()
.map(f)
}
#[doc(hidden)]
pub fn cell_id(&self) -> *const () {
Arc::as_ptr(&self.inner).cast()
}
}
impl std::fmt::Debug for GuestSecretHandle {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let state = if self.is_present() {
"present"
} else {
"consumed"
};
write!(f, "GuestSecretHandle(<{state}>)")
}
}
impl PartialEq for GuestSecretHandle {
fn eq(&self, other: &Self) -> bool {
Arc::ptr_eq(&self.inner, &other.inner)
}
}
impl serde::Serialize for GuestSecretHandle {
fn serialize<S: serde::Serializer>(&self, _serializer: S) -> Result<S::Ok, S::Error> {
Err(serde::ser::Error::custom(
"secret handles cannot be serialized; transfer them through a WIT schema-value-tree",
))
}
}
impl<'de> serde::Deserialize<'de> for GuestSecretHandle {
fn deserialize<D: serde::Deserializer<'de>>(_deserializer: D) -> Result<Self, D::Error> {
Err(serde::de::Error::custom(
"secret handles cannot be deserialized or forged from data",
))
}
}
impl IntoSchema for GuestSecretHandle {
fn type_id() -> TypeId {
TypeId::new("golem.core.Secret")
}
fn register_in(_builder: &mut SchemaBuilder) -> SchemaType {
SchemaType::secret(Default::default())
}
fn to_value(&self) -> SchemaValue {
SchemaValue::Secret(self.clone())
}
}
impl FromSchema for GuestSecretHandle {
fn from_value(value: &SchemaValue) -> Result<Self, FromSchemaError> {
match value {
SchemaValue::Secret(h) => Ok(h.clone()),
other => Err(FromSchemaError::shape_mismatch(
"secret",
format!("{other:?}"),
"Secret",
)),
}
}
}
#[derive(Clone)]
pub struct GuestPermissionCardHandle {
inner: Arc<Mutex<Option<wire::PermissionCard>>>,
}
impl GuestPermissionCardHandle {
#[doc(hidden)]
pub fn new(handle: wire::PermissionCard) -> Self {
Self {
inner: Arc::new(Mutex::new(Some(handle))),
}
}
#[doc(hidden)]
pub fn take(&self) -> Option<wire::PermissionCard> {
self.inner
.lock()
.unwrap_or_else(|poison| poison.into_inner())
.take()
}
#[doc(hidden)]
pub fn is_present(&self) -> bool {
self.inner
.lock()
.unwrap_or_else(|poison| poison.into_inner())
.is_some()
}
#[doc(hidden)]
pub fn with_handle<R>(&self, f: impl FnOnce(&wire::PermissionCard) -> R) -> Option<R> {
self.inner
.lock()
.unwrap_or_else(|poison| poison.into_inner())
.as_ref()
.map(f)
}
#[doc(hidden)]
pub fn cell_id(&self) -> *const () {
Arc::as_ptr(&self.inner).cast()
}
}
impl std::fmt::Debug for GuestPermissionCardHandle {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let state = if self.is_present() {
"present"
} else {
"consumed"
};
write!(f, "GuestPermissionCardHandle(<{state}>)")
}
}
impl PartialEq for GuestPermissionCardHandle {
fn eq(&self, other: &Self) -> bool {
Arc::ptr_eq(&self.inner, &other.inner)
}
}
impl serde::Serialize for GuestPermissionCardHandle {
fn serialize<S: serde::Serializer>(&self, _serializer: S) -> Result<S::Ok, S::Error> {
Err(serde::ser::Error::custom(
"permission-card handles cannot be serialized; transfer them through a WIT schema-value-tree",
))
}
}
impl<'de> serde::Deserialize<'de> for GuestPermissionCardHandle {
fn deserialize<D: serde::Deserializer<'de>>(_deserializer: D) -> Result<Self, D::Error> {
Err(serde::de::Error::custom(
"permission-card handles cannot be deserialized or forged from data",
))
}
}
impl IntoSchema for GuestPermissionCardHandle {
fn type_id() -> TypeId {
TypeId::new("golem.core.PermissionCard")
}
fn register_in(_builder: &mut SchemaBuilder) -> SchemaType {
SchemaType::permission_card(PermissionCardSpec::default())
}
fn to_value(&self) -> SchemaValue {
SchemaValue::PermissionCard(self.clone())
}
}
impl FromSchema for GuestPermissionCardHandle {
fn from_value(value: &SchemaValue) -> Result<Self, FromSchemaError> {
match value {
SchemaValue::PermissionCard(h) => Ok(h.clone()),
other => Err(FromSchemaError::shape_mismatch(
"permission-card",
format!("{other:?}"),
"PermissionCard",
)),
}
}
}
}
#[cfg(any(
all(feature = "guest", not(feature = "host")),
all(feature = "host", not(feature = "guest"))
))]
pub use model::*;
#[cfg(any(
all(feature = "guest", not(feature = "host")),
all(feature = "host", not(feature = "guest"))
))]
impl From<wire::Uuid> for uuid::Uuid {
fn from(value: wire::Uuid) -> Self {
uuid::Uuid::from_u64_pair(value.high_bits, value.low_bits)
}
}
#[cfg(any(
all(feature = "guest", not(feature = "host")),
all(feature = "host", not(feature = "guest"))
))]
impl From<uuid::Uuid> for wire::Uuid {
fn from(uuid: uuid::Uuid) -> Self {
let (high_bits, low_bits) = uuid.as_u64_pair();
Self {
high_bits,
low_bits,
}
}
}
#[cfg(any(
all(feature = "guest", not(feature = "host")),
all(feature = "host", not(feature = "guest"))
))]
impl From<uuid::Uuid> for wire::CardId {
fn from(uuid: uuid::Uuid) -> Self {
Self { uuid: uuid.into() }
}
}