Skip to main content

liminal_sdk/
types.rs

1use alloc::borrow::Cow;
2
3/// Schema metadata supplied by user-defined message types.
4///
5/// The SDK uses this metadata to let concrete channel implementations validate
6/// outbound payloads against the channel's declared type. The trait that returns
7/// this value is intentionally metadata-only: it does not parse schemas or run
8/// validation itself.
9#[derive(Clone, Debug, PartialEq, Eq)]
10pub struct SchemaMetadata {
11    /// Stable message schema name.
12    pub name: Cow<'static, str>,
13    /// Stable message schema version.
14    pub version: Cow<'static, str>,
15    /// Encoded schema definition bytes.
16    pub schema: Cow<'static, [u8]>,
17}
18
19impl SchemaMetadata {
20    /// Creates schema metadata from a name, version, and schema bytes.
21    #[must_use]
22    pub fn new(
23        name: impl Into<Cow<'static, str>>,
24        version: impl Into<Cow<'static, str>>,
25        schema: impl Into<Cow<'static, [u8]>>,
26    ) -> Self {
27        Self {
28            name: name.into(),
29            version: version.into(),
30            schema: schema.into(),
31        }
32    }
33}
34
35/// Compile-time marker for message types that declare schema metadata.
36///
37/// Publishing methods require this trait in addition to [`serde::Serialize`].
38/// That bound ensures a type that is merely serializable cannot be published to
39/// a typed liminal channel unless it also declares the schema metadata needed by
40/// the bus for publish-time validation.
41///
42/// Implement the trait manually today:
43///
44/// ```
45/// use liminal_sdk::{SchemaMetadata, SchemaValidate};
46/// use serde::Serialize;
47///
48/// #[derive(Serialize)]
49/// struct Created {
50///     id: String,
51/// }
52///
53/// impl SchemaValidate for Created {
54///     fn schema_metadata() -> SchemaMetadata {
55///         SchemaMetadata::new(
56///             "example.created",
57///             "1",
58///             br#"{"type":"object","required":["id"]}"#.as_slice(),
59///         )
60///     }
61/// }
62/// ```
63///
64/// A future `#[derive(SchemaValidate)]` macro is expected to generate this same
65/// implementation for supported schema-generation workflows. This crate does
66/// not provide a blanket implementation for all serializable types because doing
67/// so would remove the compile-time enforcement required by typed channels.
68pub trait SchemaValidate {
69    /// Returns this message type's schema metadata.
70    #[must_use]
71    fn schema_metadata() -> SchemaMetadata;
72}