commit 9e4ab3c50a4bcf5ba5f954017f5e6731a32e14fb
parent 58fa0ada8e0bb003cbc86e89a3b6ec1afebaeb38
Author: triesap <tyson@radroots.org>
Date: Thu, 30 Jul 2026 16:50:07 +0000
transport: define capability, maturity, availability, and status
- separate compiled source and sink operations from runtime configuration
- model experimental, preview, and stable maturity independently of availability
- preserve extensible transport identities through protocol descriptor conversion
- verify status combinations, serialization, native no-std, wasm, and workspace gates
Diffstat:
11 files changed, 554 insertions(+), 57 deletions(-)
diff --git a/contracts/codegen/protocol_v1.inventory.json b/contracts/codegen/protocol_v1.inventory.json
@@ -7,7 +7,7 @@
{
"module": "capability::v1",
"path": "crates/protocol/src/capability/v1.rs",
- "sha256": "416f3ae2a5f97c46b56b0c24095f6f6813d2851b7856c84cfbdc251bdd30a846",
+ "sha256": "ec6ee0f70283ca6ac9ef2954ae557181810b685e0b09eb7af27ce58e63e3627a",
"types": [
{
"rust_path": "radroots_protocol::capability::v1::Availability",
diff --git a/contracts/codegen/protocol_v1.inventory.sha256 b/contracts/codegen/protocol_v1.inventory.sha256
@@ -1 +1 @@
-6f9eab5185f426fed8a9e2fab514dbf19a4eecd9fdff6756db60634396023b29
+7b9f51e93a819f2d345006dc7ea6f4d9be3be3ab322d0eb791886cdee084d019
diff --git a/crates/protocol/src/capability/v1.rs b/crates/protocol/src/capability/v1.rs
@@ -112,6 +112,8 @@ impl<'de> serde::Deserialize<'de> for TransportKind {
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum Maturity {
+ /// Supported only as an experimental contract.
+ Experimental,
/// Supported as a preview contract.
Preview,
/// Supported as a stable contract.
diff --git a/crates/transport/src/capability.rs b/crates/transport/src/capability.rs
@@ -1 +1,181 @@
//! Transport-neutral capability vocabulary.
+
+use radroots_protocol::capability::v1 as protocol;
+
+/// Product maturity of a transport capability.
+#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
+#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
+#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
+pub enum Maturity {
+ /// Contract may change without compatibility guarantees.
+ Experimental,
+ /// Contract is available for preview use.
+ Preview,
+ /// Contract is supported as stable.
+ Stable,
+}
+
+/// Current runtime availability of a transport capability.
+#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
+#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
+#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
+pub enum Availability {
+ /// Fully available.
+ Available,
+ /// Available with reduced functionality.
+ Degraded,
+ /// Not currently available.
+ Unavailable,
+}
+
+impl From<protocol::Maturity> for Maturity {
+ fn from(value: protocol::Maturity) -> Self {
+ match value {
+ protocol::Maturity::Experimental => Self::Experimental,
+ protocol::Maturity::Preview => Self::Preview,
+ protocol::Maturity::Stable => Self::Stable,
+ }
+ }
+}
+
+impl From<Maturity> for protocol::Maturity {
+ fn from(value: Maturity) -> Self {
+ match value {
+ Maturity::Experimental => Self::Experimental,
+ Maturity::Preview => Self::Preview,
+ Maturity::Stable => Self::Stable,
+ }
+ }
+}
+
+impl From<protocol::Availability> for Availability {
+ fn from(value: protocol::Availability) -> Self {
+ match value {
+ protocol::Availability::Available => Self::Available,
+ protocol::Availability::Degraded => Self::Degraded,
+ protocol::Availability::Unavailable => Self::Unavailable,
+ }
+ }
+}
+
+impl From<Availability> for protocol::Availability {
+ fn from(value: Availability) -> Self {
+ match value {
+ Availability::Available => Self::Available,
+ Availability::Degraded => Self::Degraded,
+ Availability::Unavailable => Self::Unavailable,
+ }
+ }
+}
+
+/// Operations supported by an event source.
+#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
+#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
+pub struct SourceCapabilities {
+ fetch: bool,
+ discovery: bool,
+}
+
+impl SourceCapabilities {
+ /// No source operations are supported.
+ pub const NONE: Self = Self {
+ fetch: false,
+ discovery: false,
+ };
+
+ /// Bounded fetch is supported.
+ pub const FETCH: Self = Self {
+ fetch: true,
+ discovery: false,
+ };
+
+ /// Sets discovery support.
+ #[must_use]
+ pub const fn with_discovery(mut self, discovery: bool) -> Self {
+ self.discovery = discovery;
+ self
+ }
+
+ /// Whether bounded fetch is supported.
+ pub const fn can_fetch(self) -> bool {
+ self.fetch
+ }
+
+ /// Whether target discovery is supported.
+ pub const fn can_discover(self) -> bool {
+ self.discovery
+ }
+}
+
+impl From<&protocol::TransportDescriptor> for SourceCapabilities {
+ fn from(value: &protocol::TransportDescriptor) -> Self {
+ Self {
+ fetch: value.can_fetch,
+ discovery: value.can_discover,
+ }
+ }
+}
+
+/// Operations supported by an event sink.
+#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
+#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
+pub struct SinkCapabilities {
+ deliver: bool,
+ gateway_forwarding: bool,
+ receipt_observation: bool,
+}
+
+impl SinkCapabilities {
+ /// No sink operations are supported.
+ pub const NONE: Self = Self {
+ deliver: false,
+ gateway_forwarding: false,
+ receipt_observation: false,
+ };
+
+ /// Delivery is supported.
+ pub const DELIVER: Self = Self {
+ deliver: true,
+ gateway_forwarding: false,
+ receipt_observation: false,
+ };
+
+ /// Sets gateway-forwarding support.
+ #[must_use]
+ pub const fn with_gateway_forwarding(mut self, supported: bool) -> Self {
+ self.gateway_forwarding = supported;
+ self
+ }
+
+ /// Sets receipt-observation support.
+ #[must_use]
+ pub const fn with_receipt_observation(mut self, supported: bool) -> Self {
+ self.receipt_observation = supported;
+ self
+ }
+
+ /// Whether delivery is supported.
+ pub const fn can_deliver(self) -> bool {
+ self.deliver
+ }
+
+ /// Whether gateway forwarding is supported.
+ pub const fn can_gateway_forward(self) -> bool {
+ self.gateway_forwarding
+ }
+
+ /// Whether delivery receipt observation is supported.
+ pub const fn can_observe_receipts(self) -> bool {
+ self.receipt_observation
+ }
+}
+
+impl From<&protocol::TransportDescriptor> for SinkCapabilities {
+ fn from(value: &protocol::TransportDescriptor) -> Self {
+ Self {
+ deliver: value.can_deliver,
+ gateway_forwarding: value.can_gateway_forward,
+ receipt_observation: value.can_observe_receipts,
+ }
+ }
+}
diff --git a/crates/transport/src/kind.rs b/crates/transport/src/kind.rs
@@ -6,19 +6,8 @@ pub enum RadrootsTransportImplementationState {
Mock,
}
-#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
-#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
-#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub enum RadrootsTransportCapabilityMaturity {
- Preview,
- Stable,
-}
+#[doc(hidden)]
+pub type RadrootsTransportCapabilityMaturity = crate::capability::Maturity;
-#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
-#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
-#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub enum RadrootsTransportCapabilityAvailability {
- Available,
- Degraded,
- Unavailable,
-}
+#[doc(hidden)]
+pub type RadrootsTransportCapabilityAvailability = crate::capability::Availability;
diff --git a/crates/transport/src/sink.rs b/crates/transport/src/sink.rs
@@ -1,15 +1,10 @@
//! Outbound event delivery SPI and request models.
use crate::{
- Error, RadrootsTransportDeliveryReceipt, RadrootsTransportDeliveryRequest,
- RadrootsTransportStatus, source::BoxFuture,
+ Error, RadrootsTransportDeliveryReceipt, RadrootsTransportDeliveryRequest, source::BoxFuture,
};
-/// Current sink status.
-///
-/// This compatibility alias is replaced by the dedicated sink status model in
-/// the ordered capability/status checkpoint.
-pub type SinkStatus = RadrootsTransportStatus;
+pub use crate::status::SinkStatus;
/// Bounded delivery request.
///
diff --git a/crates/transport/src/source.rs b/crates/transport/src/source.rs
@@ -1,20 +1,14 @@
//! Inbound event source SPI and page models.
-use crate::{
- Error, RadrootsTransportFetchReceipt, RadrootsTransportFetchRequest, RadrootsTransportStatus,
-};
+use crate::{Error, RadrootsTransportFetchReceipt, RadrootsTransportFetchRequest};
use alloc::boxed::Box;
use core::{future::Future, pin::Pin};
+pub use crate::status::SourceStatus;
+
/// Heap-backed future returned by transport SPIs.
pub type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
-/// Current source status.
-///
-/// This compatibility alias is replaced by the dedicated source status model
-/// in the ordered capability/status checkpoint.
-pub type SourceStatus = RadrootsTransportStatus;
-
/// Bounded source request.
///
/// The dedicated bounded-page checkpoint replaces this compatibility alias
diff --git a/crates/transport/src/status.rs b/crates/transport/src/status.rs
@@ -1,9 +1,207 @@
use crate::{
RadrootsTransportCapabilityAvailability, RadrootsTransportCapabilityMaturity,
- RadrootsTransportImplementationState, RadrootsTransportKind,
+ RadrootsTransportImplementationState, RadrootsTransportKind, TransportId,
+ capability::{Availability, Maturity, SinkCapabilities, SourceCapabilities},
delivery::RadrootsTransportSatisfactionClass,
};
use alloc::string::String;
+use radroots_protocol::capability::v1::TransportDescriptor;
+
+/// Runtime state shared by source and sink capability reports.
+#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
+#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
+#[derive(Clone, Debug, Eq, PartialEq)]
+struct RuntimeStatus {
+ transport_id: TransportId,
+ configured: bool,
+ maturity: Maturity,
+ availability: Availability,
+ message: String,
+}
+
+impl RuntimeStatus {
+ fn new(
+ transport_id: TransportId,
+ configured: bool,
+ maturity: Maturity,
+ availability: Availability,
+ message: impl Into<String>,
+ ) -> Self {
+ Self {
+ transport_id,
+ configured,
+ maturity,
+ availability,
+ message: message.into(),
+ }
+ }
+
+ const fn transport_id(&self) -> TransportId {
+ self.transport_id
+ }
+
+ const fn is_configured(&self) -> bool {
+ self.configured
+ }
+
+ const fn maturity(&self) -> Maturity {
+ self.maturity
+ }
+
+ const fn availability(&self) -> Availability {
+ self.availability
+ }
+
+ fn message(&self) -> &str {
+ self.message.as_str()
+ }
+}
+
+/// Current state and operations supported by an event source.
+#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
+#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct SourceStatus {
+ #[cfg_attr(feature = "serde", serde(flatten))]
+ status: RuntimeStatus,
+ capabilities: SourceCapabilities,
+}
+
+impl SourceStatus {
+ /// Creates a source-specific status report.
+ pub fn new(
+ transport_id: TransportId,
+ configured: bool,
+ maturity: Maturity,
+ availability: Availability,
+ capabilities: SourceCapabilities,
+ message: impl Into<String>,
+ ) -> Self {
+ Self {
+ status: RuntimeStatus::new(transport_id, configured, maturity, availability, message),
+ capabilities,
+ }
+ }
+
+ /// Builds source status from the versioned passive capability catalog.
+ pub fn from_descriptor(
+ descriptor: &TransportDescriptor,
+ configured: bool,
+ message: impl Into<String>,
+ ) -> Self {
+ Self::new(
+ descriptor.kind.into(),
+ configured,
+ descriptor.maturity.into(),
+ descriptor.availability.into(),
+ SourceCapabilities::from(descriptor),
+ message,
+ )
+ }
+
+ /// Returns the extensible transport identity.
+ pub const fn transport_id(&self) -> TransportId {
+ self.status.transport_id()
+ }
+
+ /// Whether the host has configured this source.
+ pub const fn is_configured(&self) -> bool {
+ self.status.is_configured()
+ }
+
+ /// Returns the source capability's product maturity.
+ pub const fn maturity(&self) -> Maturity {
+ self.status.maturity()
+ }
+
+ /// Returns current source availability.
+ pub const fn availability(&self) -> Availability {
+ self.status.availability()
+ }
+
+ /// Returns the operator-facing status detail.
+ pub fn message(&self) -> &str {
+ self.status.message()
+ }
+
+ /// Returns supported source operations.
+ pub const fn capabilities(&self) -> SourceCapabilities {
+ self.capabilities
+ }
+}
+
+/// Current state and operations supported by an event sink.
+#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
+#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct SinkStatus {
+ #[cfg_attr(feature = "serde", serde(flatten))]
+ status: RuntimeStatus,
+ capabilities: SinkCapabilities,
+}
+
+impl SinkStatus {
+ /// Creates a sink-specific status report.
+ pub fn new(
+ transport_id: TransportId,
+ configured: bool,
+ maturity: Maturity,
+ availability: Availability,
+ capabilities: SinkCapabilities,
+ message: impl Into<String>,
+ ) -> Self {
+ Self {
+ status: RuntimeStatus::new(transport_id, configured, maturity, availability, message),
+ capabilities,
+ }
+ }
+
+ /// Builds sink status from the versioned passive capability catalog.
+ pub fn from_descriptor(
+ descriptor: &TransportDescriptor,
+ configured: bool,
+ message: impl Into<String>,
+ ) -> Self {
+ Self::new(
+ descriptor.kind.into(),
+ configured,
+ descriptor.maturity.into(),
+ descriptor.availability.into(),
+ SinkCapabilities::from(descriptor),
+ message,
+ )
+ }
+
+ /// Returns the extensible transport identity.
+ pub const fn transport_id(&self) -> TransportId {
+ self.status.transport_id()
+ }
+
+ /// Whether the host has configured this sink.
+ pub const fn is_configured(&self) -> bool {
+ self.status.is_configured()
+ }
+
+ /// Returns the sink capability's product maturity.
+ pub const fn maturity(&self) -> Maturity {
+ self.status.maturity()
+ }
+
+ /// Returns current sink availability.
+ pub const fn availability(&self) -> Availability {
+ self.status.availability()
+ }
+
+ /// Returns the operator-facing status detail.
+ pub fn message(&self) -> &str {
+ self.status.message()
+ }
+
+ /// Returns supported sink operations.
+ pub const fn capabilities(&self) -> SinkCapabilities {
+ self.capabilities
+ }
+}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
diff --git a/crates/transport/tests/capability_status.rs b/crates/transport/tests/capability_status.rs
@@ -0,0 +1,140 @@
+use radroots_transport::{
+ SinkStatus, SourceStatus, TransportId,
+ capability::{Availability, Maturity, SinkCapabilities, SourceCapabilities},
+};
+
+#[test]
+fn maturity_and_availability_round_trip_through_protocol_dtos() {
+ for maturity in [Maturity::Experimental, Maturity::Preview, Maturity::Stable] {
+ let protocol = radroots_protocol::capability::v1::Maturity::from(maturity);
+ assert_eq!(Maturity::from(protocol), maturity);
+ }
+
+ for availability in [
+ Availability::Available,
+ Availability::Degraded,
+ Availability::Unavailable,
+ ] {
+ let protocol = radroots_protocol::capability::v1::Availability::from(availability);
+ assert_eq!(Availability::from(protocol), availability);
+ }
+}
+
+#[test]
+fn runtime_state_dimensions_are_independent() {
+ let transport_id = TransportId::parse("future-mesh").expect("custom transport");
+ let states = [
+ (false, Maturity::Experimental, Availability::Available),
+ (true, Maturity::Preview, Availability::Degraded),
+ (true, Maturity::Stable, Availability::Unavailable),
+ ];
+
+ for (configured, maturity, availability) in states {
+ let status = SourceStatus::new(
+ transport_id,
+ configured,
+ maturity,
+ availability,
+ SourceCapabilities::NONE,
+ "explicit state",
+ );
+ assert_eq!(status.transport_id(), transport_id);
+ assert_eq!(status.is_configured(), configured);
+ assert_eq!(status.maturity(), maturity);
+ assert_eq!(status.availability(), availability);
+ assert_eq!(status.message(), "explicit state");
+ }
+}
+
+#[test]
+fn source_and_sink_capabilities_are_separate_contracts() {
+ let source = SourceStatus::new(
+ TransportId::NOSTR,
+ true,
+ Maturity::Stable,
+ Availability::Available,
+ SourceCapabilities::FETCH.with_discovery(true),
+ "source",
+ );
+ assert!(source.capabilities().can_fetch());
+ assert!(source.capabilities().can_discover());
+ assert_eq!(source.transport_id(), TransportId::NOSTR);
+
+ let sink = SinkStatus::new(
+ TransportId::NOSTR,
+ true,
+ Maturity::Stable,
+ Availability::Available,
+ SinkCapabilities::DELIVER
+ .with_gateway_forwarding(true)
+ .with_receipt_observation(true),
+ "sink",
+ );
+ assert!(sink.capabilities().can_deliver());
+ assert!(sink.capabilities().can_gateway_forward());
+ assert!(sink.capabilities().can_observe_receipts());
+ assert_eq!(sink.transport_id(), TransportId::NOSTR);
+}
+
+#[test]
+fn protocol_descriptors_preserve_unknown_transports_and_split_capabilities() {
+ use radroots_protocol::capability::v1::{
+ Availability as ProtocolAvailability, Maturity as ProtocolMaturity, TransportDescriptor,
+ TransportKind,
+ };
+
+ let descriptor = TransportDescriptor {
+ kind: TransportKind::parse("future-mesh").expect("custom protocol transport"),
+ maturity: ProtocolMaturity::Experimental,
+ availability: ProtocolAvailability::Degraded,
+ can_deliver: true,
+ can_fetch: false,
+ can_discover: true,
+ can_gateway_forward: true,
+ can_observe_receipts: false,
+ required_for_v1: false,
+ };
+
+ let source = SourceStatus::from_descriptor(&descriptor, false, "source not configured");
+ assert_eq!(source.transport_id().as_str(), "future-mesh");
+ assert!(!source.is_configured());
+ assert_eq!(source.maturity(), Maturity::Experimental);
+ assert_eq!(source.availability(), Availability::Degraded);
+ assert!(!source.capabilities().can_fetch());
+ assert!(source.capabilities().can_discover());
+
+ let sink = SinkStatus::from_descriptor(&descriptor, true, "sink configured");
+ assert_eq!(sink.transport_id().as_str(), "future-mesh");
+ assert!(sink.is_configured());
+ assert!(sink.capabilities().can_deliver());
+ assert!(sink.capabilities().can_gateway_forward());
+ assert!(!sink.capabilities().can_observe_receipts());
+}
+
+#[cfg(feature = "serde")]
+#[test]
+fn experimental_maturity_has_a_stable_wire_spelling() {
+ assert_eq!(
+ serde_json::to_string(&Maturity::Experimental).expect("serialize maturity"),
+ "\"experimental\""
+ );
+ assert_eq!(
+ serde_json::from_str::<Maturity>("\"experimental\"").expect("deserialize maturity"),
+ Maturity::Experimental
+ );
+
+ let status = SourceStatus::new(
+ TransportId::parse("future-mesh").expect("custom transport"),
+ true,
+ Maturity::Experimental,
+ Availability::Degraded,
+ SourceCapabilities::FETCH,
+ "degraded source",
+ );
+ let encoded = serde_json::to_string(&status).expect("serialize source status");
+ assert!(encoded.contains("\"transport_id\":\"future-mesh\""));
+ assert_eq!(
+ serde_json::from_str::<SourceStatus>(&encoded).expect("deserialize source status"),
+ status
+ );
+}
diff --git a/crates/transport/tests/spi.rs b/crates/transport/tests/spi.rs
@@ -1,10 +1,10 @@
use futures::executor::block_on;
use radroots_transport::{
BoxFuture, DeliveryReceipt, DeliveryRequest, EventSink, EventSource, FetchPage, FetchRequest,
- RadrootsTransportCapabilities, RadrootsTransportImplementationState, RadrootsTransportKind,
RadrootsTransportOutcome, RadrootsTransportOutcomeKind, RadrootsTransportPayload,
- RadrootsTransportSatisfactionPolicy, RadrootsTransportStatus, RadrootsTransportTarget,
- RadrootsTransportTargetReceipt, RadrootsTransportTargetSet, SinkStatus, SourceStatus,
+ RadrootsTransportSatisfactionPolicy, RadrootsTransportTarget, RadrootsTransportTargetReceipt,
+ RadrootsTransportTargetSet, SinkStatus, SourceStatus, TransportId,
+ capability::{Availability, Maturity, SinkCapabilities, SourceCapabilities},
};
struct SourceOnly;
@@ -82,26 +82,26 @@ impl EventSink for Bidirectional {
}
}
-fn source_status() -> RadrootsTransportStatus {
- RadrootsTransportStatus::new(
- RadrootsTransportKind::Local,
+fn source_status() -> SourceStatus {
+ SourceStatus::new(
+ TransportId::LOCAL,
true,
- RadrootsTransportImplementationState::Real,
- false,
+ Maturity::Stable,
+ Availability::Available,
+ SourceCapabilities::FETCH,
"source ready",
)
- .with_capabilities(RadrootsTransportCapabilities::fetch_only())
}
-fn sink_status() -> RadrootsTransportStatus {
- RadrootsTransportStatus::new(
- RadrootsTransportKind::Local,
- true,
- RadrootsTransportImplementationState::Real,
+fn sink_status() -> SinkStatus {
+ SinkStatus::new(
+ TransportId::LOCAL,
true,
+ Maturity::Stable,
+ Availability::Available,
+ SinkCapabilities::DELIVER,
"sink ready",
)
- .with_capabilities(RadrootsTransportCapabilities::deliver_only())
}
fn target_set() -> RadrootsTransportTargetSet {
@@ -122,15 +122,13 @@ fn source_only_and_sink_only_implementations_are_independently_dispatchable() {
assert_sink_dyn_compatible(&sink);
let source_status = block_on(EventSource::status(&source)).expect("source status");
- assert!(source_status.capabilities.fetch);
- assert!(!source_status.capabilities.deliver);
+ assert!(source_status.capabilities().can_fetch());
let page =
block_on(source.fetch(FetchRequest::new("fetch-1", target_set()))).expect("fetch page");
assert_eq!(page.request_id, "fetch-1");
let sink_status = block_on(EventSink::status(&sink)).expect("sink status");
- assert!(sink_status.capabilities.deliver);
- assert!(!sink_status.capabilities.fetch);
+ assert!(sink_status.capabilities().can_deliver());
let receipt = block_on(
sink.deliver(
DeliveryRequest::new(
@@ -158,13 +156,13 @@ fn a_bidirectional_adapter_exposes_both_dyn_contracts() {
assert!(
block_on(EventSource::status(&adapter))
.expect("source status")
- .capabilities
- .fetch
+ .capabilities()
+ .can_fetch()
);
assert!(
block_on(EventSink::status(&adapter))
.expect("sink status")
- .capabilities
- .deliver
+ .capabilities()
+ .can_deliver()
);
}
diff --git a/docs/api/radroots_protocol.txt b/docs/api/radroots_protocol.txt
@@ -19,6 +19,7 @@ impl core::error::Error for radroots_protocol::capability::v1::Error
impl core::fmt::Display for radroots_protocol::capability::v1::Error
pub fn radroots_protocol::capability::v1::Error::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
pub enum radroots_protocol::capability::v1::Maturity
+pub radroots_protocol::capability::v1::Maturity::Experimental
pub radroots_protocol::capability::v1::Maturity::Preview
pub radroots_protocol::capability::v1::Maturity::Stable
pub struct radroots_protocol::capability::v1::MeshScopeId