Skip to main content

prns_runtime/runtime/
command.rs

1use crate::engine::{
2    AnnounceAppData, AnnounceNow, AnnounceTarget, CommandId, PacketReceiptDelivered, PrnsCommand,
3    SendSinglePacketFailure,
4};
5pub use crate::engine::{DropRouteOutcome, DropRoutesViaOutcome};
6use crate::identity::{
7    IdentityHash, MarkDestinationUsedOutcome, ReleaseDestinationOutcome, RetainDestinationOutcome,
8    RetainIdentityOutcome,
9};
10use crate::routing::links::LinkId;
11use crate::wire::{DestinationHash, TransportId};
12
13use super::request_endpoints::RespondToken;
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16pub struct ClearAnnounceQueuesOutcome {
17    pub dropped_announces: u32,
18}
19
20/// Why an awaited send never reached `Delivered`.
21#[derive(Debug, Clone, Copy, PartialEq, Eq)]
22pub enum SendError<F> {
23    PayloadTooLarge,
24    NodeStopped,
25    /// More awaited sends are in flight than the platform tracks at once
26    Busy,
27    Failed(F),
28}
29
30#[derive(Debug, Clone, Copy, PartialEq, Eq)]
31pub enum RoutingControlError {
32    NodeStopped,
33    Busy,
34}
35
36pub trait RoutingControl {
37    fn drop_route(
38        &self,
39        destination: DestinationHash,
40    ) -> impl core::future::Future<Output = Result<DropRouteOutcome, RoutingControlError>> + Send;
41
42    fn drop_routes_via(
43        &self,
44        transport: TransportId,
45    ) -> impl core::future::Future<Output = Result<DropRoutesViaOutcome, RoutingControlError>> + Send;
46
47    fn clear_announce_queues(
48        &self,
49    ) -> impl core::future::Future<Output = Result<ClearAnnounceQueuesOutcome, RoutingControlError>> + Send;
50}
51
52#[derive(Debug, Clone, Copy, PartialEq, Eq)]
53pub enum DestinationIdentityRetentionControlError {
54    NodeStopped,
55    Busy,
56}
57
58pub trait DestinationIdentityRetentionControl {
59    fn mark_destination_used(
60        &self,
61        destination: DestinationHash,
62    ) -> impl core::future::Future<
63        Output = Result<MarkDestinationUsedOutcome, DestinationIdentityRetentionControlError>,
64    > + Send;
65
66    fn retain_destination(
67        &self,
68        destination: DestinationHash,
69    ) -> impl core::future::Future<
70        Output = Result<RetainDestinationOutcome, DestinationIdentityRetentionControlError>,
71    > + Send;
72
73    fn release_destination(
74        &self,
75        destination: DestinationHash,
76    ) -> impl core::future::Future<
77        Output = Result<ReleaseDestinationOutcome, DestinationIdentityRetentionControlError>,
78    > + Send;
79
80    fn retain_identity(
81        &self,
82        identity: IdentityHash,
83    ) -> impl core::future::Future<
84        Output = Result<RetainIdentityOutcome, DestinationIdentityRetentionControlError>,
85    > + Send;
86}
87
88/// The high-level API shared by every platform's node handle. Tokio carries commands over an unbounded channel with per-command oneshots; Embassy uses a bounded channel and static completion pool.
89///
90/// [`issue`](Self::issue) returns a minted [`CommandId`] immediately, while awaited operations settle through that id. Platform-specific capabilities remain inherent methods on the concrete handle.
91#[allow(async_fn_in_trait)]
92pub trait PrnsNodeApi {
93    /// Queues an engine command and returns the [`CommandId`] it was minted under. If you're looking for its settlement, watch the event stream for the settlement tagged with that CommandId.
94    ///
95    /// You may not ever need this, since many operations have their own convenience methods, usually `await`able.
96    fn issue(&self, command: PrnsCommand) -> Option<CommandId>;
97
98    /// Announce `destination` on every interface with its registered app_data: RNS 1.4.2 `Destination.announce()` with no arguments.
99    ///
100    /// Returns `None` if the node has stopped. If you want to target a specific interface or provide explicit app_data, [`issue`](Self::issue) a custom [`AnnounceNow`]. Some platform implementations may provide an awaitable convenience method, specifically for `announce_now`, on top of this.
101    fn announce(&self, destination: DestinationHash) -> Option<CommandId> {
102        self.issue(PrnsCommand::AnnounceNow(AnnounceNow {
103            destination,
104            target: AnnounceTarget::AllInterfaces,
105            app_data: AnnounceAppData::Registered,
106        }))
107    }
108
109    async fn send_single_packet(
110        &self,
111        destination: DestinationHash,
112        data: &[u8],
113    ) -> Result<PacketReceiptDelivered, SendError<SendSinglePacketFailure>>;
114
115    fn respond_packed(&self, responder: RespondToken, packed: &[u8]) -> bool;
116
117    fn close_link(&self, link_id: LinkId) -> bool;
118}