Skip to main content

ridl_rt/
port.rs

1//! The ports: the traits a runtime implements and generated code calls.
2//!
3//! Every port method returns without waiting. Waiting — blocking, `async`, or
4//! a loop that drives the runtime — belongs to a face over a port, and this
5//! crate defines no face. A port carries interface numbers, ordinals and
6//! bytes, never a payload type: the generated binding decodes. No port method
7//! takes the current time; a runtime reads its own [`Clock`].
8//!
9//! A port is attached to one catalog ([`Attached`]), and the interface numbers
10//! and ordinals its methods take are scoped by that catalog.
11//!
12//! [`ScannableSignals`] and [`CoherentSignals`] are extensions. They describe
13//! mechanisms some runtimes have, not interaction semantics every runtime must
14//! present, so a runtime may omit them. [`Wakeable`] is an extension too: it
15//! is how a face that waits learns when to read a port again, and a runtime
16//! that serves a generated async client implements it.
17//!
18//! Each trait below names the generated method it backs, so a reader who
19//! arrived from generated code can find the port under it. The crate-level
20//! documentation has the whole table, and
21//! `docs/technotes/ridl-rt-by-example.md` in this repository walks it against
22//! concrete generated code.
23
24use core::task::Waker;
25
26use crate::contract::{CatalogRef, InterfaceNo, Ordinal};
27use crate::error::{CallError, Contract};
28use crate::sample::{Duration, Envelope, Freshness, Provenance, Timestamp};
29
30/// A port attached to one catalog.
31pub trait Attached {
32    /// The catalog this port serves.
33    fn catalog(&self) -> &CatalogRef;
34}
35
36/// The clock envelopes are stamped from. A runtime has one.
37pub trait Clock {
38    /// The current time in the platform time base.
39    fn now(&self) -> Timestamp;
40}
41
42/// Signals, consumer side.
43///
44/// A generated `Client` has one method per signal over this port. It reads
45/// into a stack buffer sized from the payload's
46/// [`MAX_SIZE`](crate::payload::Payload::MAX_SIZE), checks the bytes, and
47/// returns a [`Sample`](crate::sample::Sample). Bytes that fail their check
48/// are not an error there: the sample carries the channel's init value and a
49/// provenance of [`Invalid`](crate::sample::Provenance::Invalid), so the
50/// [`ReadError`] here reports the read itself.
51pub trait SignalReader: Attached {
52    /// Copies the signal's current value into the front of `out` and returns
53    /// its provenance, its freshness and its envelope. The runtime resolves
54    /// both the provenance and the freshness.
55    ///
56    /// A sample whose provenance is `Init` or `Invalid(Declared)` may carry
57    /// zero bytes, because the runtime has no value to copy; `len` is then 0,
58    /// and a generated face returns the channel's init value under that
59    /// provenance (ADR-0021 decision 17).
60    ///
61    /// Returns `ReadError::Short` when `out` is shorter than the value.
62    fn read(
63        &self,
64        iface: InterfaceNo,
65        ord: Ordinal,
66        out: &mut [u8],
67    ) -> Result<RawSample, ReadError>;
68}
69
70/// What [`SignalReader::read`] returns beside the copied bytes.
71#[derive(Clone, Copy, Debug, PartialEq, Eq)]
72pub struct RawSample {
73    /// Where the value comes from.
74    pub provenance: Provenance,
75    /// How old the value is.
76    pub freshness: Freshness,
77    /// The sender's timestamp and sequence number.
78    pub envelope: Envelope,
79    /// The number of bytes copied into `out`.
80    pub len: usize,
81}
82
83/// Signals, provider side.
84///
85/// `set`, `invalidate` and `touch` stage a change. Each fails with
86/// [`WriteError::Contract`] when the ordinal names no member, and with
87/// [`WriteError::NotOwner`] when it names a member this provider does not
88/// own. `commit` publishes every staged change, with one generation
89/// increment and one timestamp per interface, taken from the runtime's
90/// [`Clock`].
91///
92/// A generated `Publisher` has one method per signal over `set`, plus an
93/// `invalidate_<name>` and a `commit`. The staging split is why a provider
94/// that updates several signals of one interface and then commits produces one
95/// coherent publication rather than several.
96pub trait SignalWriter: Attached {
97    /// Stages a new value.
98    fn set(&mut self, iface: InterfaceNo, ord: Ordinal, bytes: &[u8]) -> Result<(), WriteError>;
99    /// Stages the invalid state (ridl §4.5), with
100    /// [`Cause::Declared`](crate::sample::Cause::Declared).
101    fn invalidate(&mut self, iface: InterfaceNo, ord: Ordinal) -> Result<(), WriteError>;
102    /// Stages a re-affirmation of the current value, without a new value.
103    fn touch(&mut self, iface: InterfaceNo, ord: Ordinal) -> Result<(), WriteError>;
104    /// Publishes everything staged. It cannot fail, so it reports nothing —
105    /// including that the runtime behind the port is gone. A caller learns
106    /// that from [`WriteError::Detached`] on a later `set`, `invalidate` or
107    /// `touch`, never from that `commit`. What becomes of the changes staged
108    /// before a commit whose runtime has already detached is not fixed here.
109    fn commit(&mut self);
110}
111
112/// Events, consumer side.
113///
114/// A generated `Client` has a `subscribe_<name>` per event, but a single
115/// `next_event` for the whole interface, because [`next`](EventSource::next)
116/// returns the next occurrence of anything subscribed and the payload type is
117/// not known until its ordinal has been read. The generated method routes on
118/// that ordinal into an enum with one variant per event.
119pub trait EventSource: Attached {
120    /// Starts delivery of the listed events.
121    fn subscribe(&mut self, iface: InterfaceNo, ords: &[Ordinal]) -> Result<(), SubscribeError>;
122    /// Stops delivery of the listed events.
123    fn unsubscribe(&mut self, iface: InterfaceNo, ords: &[Ordinal]);
124    /// Copies the next occurrence into the front of `out`. `Ok(None)` when no
125    /// occurrence is waiting.
126    ///
127    /// Occurrences come in order, and a gap in `seq` is a loss (ridl §3.1). An
128    /// occurrence older than its time to live is discarded here (ridl §5.2).
129    /// `ReadError::Short` does not consume the occurrence: the next call
130    /// returns the same one.
131    fn next(&mut self, out: &mut [u8]) -> Result<Option<RawOccurrence>, ReadError>;
132}
133
134/// What [`EventSource::next`] returns beside the copied bytes.
135#[derive(Clone, Copy, Debug, PartialEq, Eq)]
136pub struct RawOccurrence {
137    /// The interface of the event.
138    pub iface: InterfaceNo,
139    /// The ordinal of the event.
140    pub ord: Ordinal,
141    /// The sender's timestamp and sequence number.
142    pub envelope: Envelope,
143    /// The number of bytes copied into `out`.
144    pub len: usize,
145}
146
147/// Events, provider side.
148///
149/// A generated `Publisher` has one method per event over this port. Unlike a
150/// signal, an occurrence is not staged and there is no `commit`: there is no
151/// coherent set to assemble.
152pub trait EventSink: Attached {
153    /// Raises one occurrence.
154    fn raise(&mut self, iface: InterfaceNo, ord: Ordinal, bytes: &[u8]) -> Result<(), RaiseError>;
155}
156
157/// Calls, consumer side.
158///
159/// A command and a query are separate methods, because their outcomes differ
160/// (ridl §6, §7).
161///
162/// A generated `Client` has one method per command and query over this port,
163/// each returning a named future rather than an outcome, because nothing
164/// here waits. The method sends when it is called; the future's `poll` reads
165/// the outcome — [`ack`](Caller::ack) for a command, [`reply`](Caller::reply)
166/// for a query — and calls [`forget`](Caller::forget) when it leaves the
167/// waiting phase. A `require` clause is evaluated before sending, so a
168/// failing precondition costs no round trip and is reported as
169/// [`SendError::Contract`].
170pub trait Caller: Attached {
171    /// Sends a command and returns the correlation of its outcome.
172    fn command(
173        &mut self,
174        iface: InterfaceNo,
175        ord: Ordinal,
176        args: &[u8],
177    ) -> Result<Correlation, SendError>;
178    /// Sends a query and returns the correlation of its reply.
179    fn query(
180        &mut self,
181        iface: InterfaceNo,
182        ord: Ordinal,
183        args: &[u8],
184    ) -> Result<Correlation, SendError>;
185    /// A command's delivery acknowledgment (ridl §6.1), once it is known:
186    /// `Ok(())` when accepted, `Err(CallError::Contract(_))` when rejected,
187    /// `Err(CallError::Transport(Transport::Corrupt))` when the provider could
188    /// not read the command's argument bytes,
189    /// `Err(CallError::Transport(Transport::Busy))` when the providing runtime
190    /// refused the command at admission, and
191    /// `Err(CallError::Transport(Transport::Undelivered))` when no
192    /// acknowledgment came within the bound. `None` while unknown, and always
193    /// `None` for a query's correlation.
194    ///
195    /// `None` has two causes this method does not separate: the acknowledgment
196    /// is not known yet, and `c` is a query's correlation, for which `None` is
197    /// the standing answer. A caller that polls `ack` for a query's
198    /// correlation therefore never finishes. The return carries no error, so
199    /// keep the correlations [`command`](Caller::command) returned and ask
200    /// only about those. After [`forget`](Caller::forget) a correlation's
201    /// outcome is no longer retrievable, so do not ask about it.
202    fn ack(&mut self, c: Correlation) -> Option<Result<(), CallError>>;
203    /// A query's reply, once it is known: the reply bytes copied into the front
204    /// of `out` and their length, or the error. `Ok(None)` while unknown.
205    /// `ReadError::Short` does not consume the reply.
206    ///
207    /// The outer [`ReadError`] reports the port call itself: `Short` when
208    /// `out` is too short, and `Detached` when the local runtime is gone.
209    /// `reply` never returns `ReadError::Contract`. The inner [`CallError`] is
210    /// the outcome from the peer or the transport, such as a contract error
211    /// the provider settled, or `Transport::Down` when the connection to the
212    /// peer is lost.
213    fn reply(
214        &mut self,
215        c: Correlation,
216        out: &mut [u8],
217    ) -> Result<Option<Result<usize, CallError>>, ReadError>;
218    /// Releases a correlation whose outcome the caller no longer needs.
219    fn forget(&mut self, c: Correlation);
220}
221
222/// Identifies one sent call to its caller.
223#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
224pub struct Correlation(pub u64);
225
226/// Calls, provider side.
227///
228/// `next_claim` presents each delivered call once. A retransmission of a call
229/// already presented is not presented again and receives the cached
230/// acknowledgment. The one call presented again is a claim a dropped handler
231/// held and did not settle: the runtime returns it to the waiting calls, so
232/// another handler that serves the member can take it, as many times as a
233/// holder is dropped (ADR-0021 decision 5). Calls from two callers are never
234/// merged, even when they carry the same `seq`. A call lost in transport is never presented. The
235/// caller of a lost command sees `Transport::Undelivered` from `Caller::ack`;
236/// the caller of a lost query sees `Transport::Timeout` from `Caller::reply`
237/// once the response bound passes.
238///
239/// Every claim is settled. For a command, the generated dispatch settles
240/// `Ok(&[])` after the arguments and `require` pass, before application code
241/// runs. For a query, it settles with the reply bytes or the outcome the
242/// caller sees.
243///
244/// An application implements neither this trait nor a claim loop. It
245/// implements the generated `Provider` trait and polls the future the
246/// generated `serve` returns, which on each poll makes one pass over the
247/// claims already waiting, routes each by ordinal, decodes, evaluates
248/// `require`, calls the provider, evaluates a query's `ensure`, and settles.
249/// That future resolves in two cases only: at once, when this port's `serve`
250/// refused the members, and later, when this port fails.
251pub trait Handler: Attached {
252    /// Starts presenting calls to the listed members.
253    fn serve(&mut self, iface: InterfaceNo, ords: &[Ordinal]) -> Result<(), ServeError>;
254    /// Copies the next call's arguments into the front of `out`. `Ok(None)`
255    /// when no call is waiting. `ReadError::Short` does not consume the call.
256    fn next_claim(&mut self, out: &mut [u8]) -> Result<Option<Claim>, ReadError>;
257    /// Settles a claim with the reply bytes (empty for a command) or the
258    /// outcome the caller sees. A provider settles
259    /// [`CallError::Contract`] when the arguments break their typl
260    /// constraints, a `require` clause fails, or an `ensure` clause fails,
261    /// and `CallError::Transport(Transport::Corrupt)` when the argument
262    /// bytes fail the structure check.
263    fn settle(
264        &mut self,
265        claim: ClaimId,
266        outcome: Result<&[u8], CallError>,
267    ) -> Result<(), SettleError>;
268}
269
270/// One call presented to a provider.
271#[derive(Clone, Copy, Debug, PartialEq, Eq)]
272pub struct Claim {
273    /// Unique in its channel.
274    pub id: ClaimId,
275    /// The interface of the call.
276    pub iface: InterfaceNo,
277    /// The ordinal of the call. The descriptor at this ordinal gives the kind.
278    pub ord: Ordinal,
279    /// The caller's timestamp and sequence number. `seq` is unique for each
280    /// caller, not for each channel.
281    pub envelope: Envelope,
282    /// The time left before the response bound passes. `None` when the call
283    /// has no response bound (ridl §9.3).
284    pub remaining: Option<Duration>,
285    /// The number of argument bytes copied into `out`.
286    pub len: usize,
287}
288
289/// Identifies one claim to its provider.
290#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
291pub struct ClaimId(pub u64);
292
293/// `fixed`, consumer side (ridl §8).
294///
295/// The generated face carries no method over this port in this version: a
296/// `fixed` is provisioned rather than interacted with, so the emitter writes
297/// its descriptor and nothing else, and an application that needs a
298/// provisioned value calls [`read_fixed`](FixedReader::read_fixed) itself.
299/// There is no provider side either — a provisioned constant is supplied to
300/// the runtime, not published by application code.
301pub trait FixedReader: Attached {
302    /// Copies the provisioned value into the front of `out` and returns its
303    /// length.
304    fn read_fixed(
305        &self,
306        iface: InterfaceNo,
307        ord: Ordinal,
308        out: &mut [u8],
309    ) -> Result<usize, ReadError>;
310}
311
312/// Extension: signals in a store a consumer can walk. A runtime may omit it.
313pub trait ScannableSignals: SignalReader {
314    /// The interface's generation: a counter that each commit to the interface
315    /// increments.
316    ///
317    /// The return carries no error, so an interface the port's catalog does
318    /// not hold has no reserved answer: it gives a `u64` the caller cannot
319    /// tell from a real generation. Ask only about an interface of
320    /// [`catalog`](Attached::catalog).
321    fn generation(&self, iface: InterfaceNo) -> u64;
322    /// Writes the changes into `out`, interface by interface, in the order of
323    /// `marks`, and updates `marks`. An interface's changes are written all
324    /// together or not at all: when they do not fit in the rest of `out`,
325    /// none of them is written, that interface's mark is not updated, and
326    /// `scan` returns the number of entries written so far.
327    ///
328    /// The count alone does not say whether changes are still waiting, because
329    /// a return of 0 has two causes. To tell them apart, compare each mark
330    /// with its interface's [`generation`](ScannableSignals::generation) after
331    /// the call:
332    ///
333    /// - every mark's `generation` equals `generation(iface)` — nothing had
334    ///   changed, and the scan is complete;
335    /// - some mark's `generation` is behind `generation(iface)` — that
336    ///   interface's changes did not fit in `out`. When `scan` also returned
337    ///   0, `out` is shorter than the changes of the first such interface in
338    ///   the order of `marks`, and no call can make progress until `out` is
339    ///   longer.
340    ///
341    /// A caller that scans in a loop therefore grows `out` when `scan` returns
342    /// 0 and a mark is still behind its interface's generation.
343    fn scan(&self, marks: &mut [Watermark], out: &mut [Changed]) -> usize;
344}
345
346/// How far a consumer has scanned one interface.
347#[derive(Clone, Copy, Debug, PartialEq, Eq)]
348pub struct Watermark {
349    /// The interface.
350    pub iface: InterfaceNo,
351    /// The generation last scanned. Named `generation`, not `gen`, because
352    /// `gen` is a reserved keyword in the 2024 edition.
353    pub generation: u64,
354    /// The sequence number last scanned.
355    pub seq: u64,
356}
357
358/// A signal that changed since a [`Watermark`].
359#[derive(Clone, Copy, Debug, PartialEq, Eq)]
360pub struct Changed {
361    /// The interface of the signal.
362    pub iface: InterfaceNo,
363    /// The ordinal of the signal.
364    pub ord: Ordinal,
365    /// The signal's sequence number.
366    pub seq: u64,
367}
368
369/// Extension: reads of several signals of one interface from one publication.
370/// A runtime whose binding delivers each field separately cannot present this
371/// and omits it.
372pub trait CoherentSignals: SignalReader {
373    /// Answers every ordinal in `ords` from one publication. Copies the values
374    /// into `out` one after another, writes one `RawSample` for each ordinal
375    /// into `samples` in the order of `ords`, and returns the number of bytes
376    /// written to `out`.
377    ///
378    /// Returns `ReadError::Short` with the size the whole set needs when `out`
379    /// is too short, `ReadError::TooFewSamples` with the number of entries
380    /// `samples` needs when `samples` is shorter than `ords`, and
381    /// `ReadError::Contract(Contract::UnknownInteraction)` when an ordinal
382    /// names no member.
383    fn read_coherent(
384        &self,
385        iface: InterfaceNo,
386        ords: &[Ordinal],
387        out: &mut [u8],
388        samples: &mut [RawSample],
389    ) -> Result<usize, ReadError>;
390}
391
392/// Extension: a port that can wake a task. A runtime that serves a generated
393/// async client implements it.
394///
395/// No port method waits, so a task registers its interest here, reads the
396/// port, and returns when the read finds nothing; the runtime wakes the task
397/// when the thing it waits for may have changed, and the task reads the port
398/// again.
399///
400/// The contract:
401///
402/// - **One waker per kind of key per handle.** [`wake_on`](Wakeable::wake_on)
403///   stores a clone of `waker` on the handle it is called on, one for each
404///   kind — `Slot`, `Event`, `Claim` — and an `Outcome` waker with its call.
405///   A change to any key of that kind that the handle observes wakes the
406///   stored waker, so a task that registers `Event(a)` and then `Event(b)` is
407///   woken by an occurrence of either; the task reads the port again and
408///   finds out which.
409/// - **A refresh or a displacement.** A `wake_on` whose waker
410///   [`will_wake`](Waker::will_wake) the stored one is a refresh:
411///   it replaces the stored waker without waking it, because a task
412///   registers on every poll and waking it for its own registration would
413///   schedule the next poll from every poll. A waker of another task
414///   displaces the stored one, and the displaced waker is woken, so no task
415///   waits on a registration that can no longer fire. A second task waiting
416///   for the same events holds a second handle, and each handle's waiter is
417///   woken.
418/// - **Woken at most once.** A stored waker is woken after every change of
419///   its kind becomes visible, and is cleared when woken. A spurious wake is
420///   allowed: a runtime with one unkeyed "something changed" source may wake
421///   every waiter it holds on any change.
422/// - **Register, then read.** The caller registers on every poll, and
423///   registers before it reads the port, so a change between the read and
424///   the return still wakes it.
425///
426/// [`Interest::Event`] and [`Interest::Claim`] are keyed per interface,
427/// because [`EventSource::next`] and [`Handler::next_claim`] drain one queue
428/// whatever the ordinal, and the subscription and the served set already
429/// filter by member.
430pub trait Wakeable {
431    /// Wakes `waker` when the thing `what` names may have changed, under the
432    /// contract above.
433    fn wake_on(&self, what: Interest, waker: &Waker);
434}
435
436/// What a task waits for, as [`Wakeable::wake_on`] takes it.
437///
438/// Exhaustive: a runtime handles every key, because an unknown key has no
439/// safe default. Ignoring it leaves the waiter waiting, and waking it at once
440/// makes a busy loop. A new key is a 0.x minor (ADR-0021 decision 13).
441#[derive(Clone, Copy, Debug, PartialEq, Eq)]
442pub enum Interest {
443    /// The outcome of one call is known.
444    Outcome(Correlation),
445    /// A slot for a new call is free.
446    Slot,
447    /// An occurrence of one of the interface's events is waiting.
448    Event(InterfaceNo),
449    /// A claim on one of the interface's members is waiting.
450    Claim(InterfaceNo),
451}
452
453/// A read that failed.
454///
455/// One enum serves every read on every port, so a variant can be unreachable
456/// for the method that returns it: [`TooFewSamples`](ReadError::TooFewSamples)
457/// belongs to [`CoherentSignals::read_coherent`] alone, and
458/// [`Caller::reply`] never returns [`Contract`](ReadError::Contract). Each
459/// method documents what it can return.
460#[non_exhaustive]
461#[derive(Clone, Copy, Debug, PartialEq, Eq)]
462pub enum ReadError {
463    /// The output buffer is too short. Nothing was consumed.
464    Short {
465        /// The bytes the read needs.
466        needed: usize,
467    },
468    /// `samples` has fewer entries than `ords`. Nothing was consumed.
469    TooFewSamples {
470        /// The entries `samples` needs.
471        needed: usize,
472    },
473    /// A contract error, such as an unknown interaction.
474    Contract(Contract),
475    /// The runtime behind the port is gone.
476    Detached,
477}
478
479/// A [`SignalWriter::set`], [`SignalWriter::invalidate`] or
480/// [`SignalWriter::touch`] that failed.
481#[non_exhaustive]
482#[derive(Clone, Copy, Debug, PartialEq, Eq)]
483pub enum WriteError {
484    /// The value is larger than the signal's capacity.
485    TooLarge {
486        /// The capacity in bytes.
487        cap: usize,
488    },
489    /// This provider does not own the signal.
490    NotOwner,
491    /// A contract error, such as an unknown interaction.
492    Contract(Contract),
493    /// The runtime behind the port is gone.
494    Detached,
495}
496
497/// An [`EventSink::raise`] that failed.
498#[non_exhaustive]
499#[derive(Clone, Copy, Debug, PartialEq, Eq)]
500pub enum RaiseError {
501    /// The runtime cannot accept an occurrence now. Retryable.
502    Busy,
503    /// The occurrence is larger than the event's capacity.
504    TooLarge {
505        /// The capacity in bytes.
506        cap: usize,
507    },
508    /// This provider does not own the event.
509    NotOwner,
510    /// A contract error, such as an unknown interaction.
511    Contract(Contract),
512    /// The runtime behind the port is gone.
513    Detached,
514}
515
516/// A [`Caller::command`] or [`Caller::query`] that failed before sending.
517#[non_exhaustive]
518#[derive(Clone, Copy, Debug, PartialEq, Eq)]
519pub enum SendError {
520    /// The runtime cannot accept a call now. Retryable.
521    Busy,
522    /// The arguments are larger than the call's capacity.
523    TooLarge {
524        /// The capacity in bytes.
525        cap: usize,
526    },
527    /// A contract error, such as an unknown interaction.
528    Contract(Contract),
529    /// The runtime behind the port is gone.
530    Detached,
531}
532
533/// An [`EventSource::subscribe`] that failed.
534#[non_exhaustive]
535#[derive(Clone, Copy, Debug, PartialEq, Eq)]
536pub enum SubscribeError {
537    /// A contract error: an unknown interaction fails when subscribing (ridl
538    /// §10.2).
539    Contract(Contract),
540    /// The runtime behind the port is gone.
541    Detached,
542}
543
544/// A [`Handler::serve`] that failed.
545#[non_exhaustive]
546#[derive(Clone, Copy, Debug, PartialEq, Eq)]
547pub enum ServeError {
548    /// A contract error, such as an unknown interaction.
549    Contract(Contract),
550    /// This provider does not own the call.
551    NotOwner,
552    /// The runtime behind the port is gone.
553    Detached,
554}
555
556/// A [`Handler::settle`] that failed.
557#[non_exhaustive]
558#[derive(Clone, Copy, Debug, PartialEq, Eq)]
559pub enum SettleError {
560    /// The claim was already settled, or was never issued.
561    UnknownClaim,
562    /// The reply is larger than the call's capacity.
563    TooLarge {
564        /// The capacity in bytes.
565        cap: usize,
566    },
567    /// The runtime behind the port is gone.
568    Detached,
569}
570
571// Forwarding impls (ADR-0021 decision 11).
572//
573// Every port trait above is implemented for `&mut P`, and the seven whose
574// methods all take `&self` — `Attached`, `Clock`, `SignalReader`,
575// `FixedReader`, `ScannableSignals`, `CoherentSignals` and `Wakeable` — also
576// for `&P`.
577// What they buy is one thing: a value generic over a port trait, such as a
578// generated face, can be built over a reference to a port rather than over the
579// port itself. A wrapper that adds tracing and a test double are accepted by
580// such a bound with or without them, because each implements the port traits
581// itself.
582//
583// `impl<P: T + ?Sized> T for Box<P>` is deferred: it needs `alloc`, which only
584// the `std` feature brings in, and nothing needs a boxed port (ADR-0021 open
585// question 5).
586
587impl<P: Attached + ?Sized> Attached for &P {
588    fn catalog(&self) -> &CatalogRef {
589        (**self).catalog()
590    }
591}
592
593impl<P: Attached + ?Sized> Attached for &mut P {
594    fn catalog(&self) -> &CatalogRef {
595        (**self).catalog()
596    }
597}
598
599impl<P: Clock + ?Sized> Clock for &P {
600    fn now(&self) -> Timestamp {
601        (**self).now()
602    }
603}
604
605impl<P: Clock + ?Sized> Clock for &mut P {
606    fn now(&self) -> Timestamp {
607        (**self).now()
608    }
609}
610
611impl<P: SignalReader + ?Sized> SignalReader for &P {
612    fn read(
613        &self,
614        iface: InterfaceNo,
615        ord: Ordinal,
616        out: &mut [u8],
617    ) -> Result<RawSample, ReadError> {
618        (**self).read(iface, ord, out)
619    }
620}
621
622impl<P: SignalReader + ?Sized> SignalReader for &mut P {
623    fn read(
624        &self,
625        iface: InterfaceNo,
626        ord: Ordinal,
627        out: &mut [u8],
628    ) -> Result<RawSample, ReadError> {
629        (**self).read(iface, ord, out)
630    }
631}
632
633impl<P: SignalWriter + ?Sized> SignalWriter for &mut P {
634    fn set(&mut self, iface: InterfaceNo, ord: Ordinal, bytes: &[u8]) -> Result<(), WriteError> {
635        (**self).set(iface, ord, bytes)
636    }
637    fn invalidate(&mut self, iface: InterfaceNo, ord: Ordinal) -> Result<(), WriteError> {
638        (**self).invalidate(iface, ord)
639    }
640    fn touch(&mut self, iface: InterfaceNo, ord: Ordinal) -> Result<(), WriteError> {
641        (**self).touch(iface, ord)
642    }
643    fn commit(&mut self) {
644        (**self).commit();
645    }
646}
647
648impl<P: EventSource + ?Sized> EventSource for &mut P {
649    fn subscribe(&mut self, iface: InterfaceNo, ords: &[Ordinal]) -> Result<(), SubscribeError> {
650        (**self).subscribe(iface, ords)
651    }
652    fn unsubscribe(&mut self, iface: InterfaceNo, ords: &[Ordinal]) {
653        (**self).unsubscribe(iface, ords);
654    }
655    fn next(&mut self, out: &mut [u8]) -> Result<Option<RawOccurrence>, ReadError> {
656        (**self).next(out)
657    }
658}
659
660impl<P: EventSink + ?Sized> EventSink for &mut P {
661    fn raise(&mut self, iface: InterfaceNo, ord: Ordinal, bytes: &[u8]) -> Result<(), RaiseError> {
662        (**self).raise(iface, ord, bytes)
663    }
664}
665
666impl<P: Caller + ?Sized> Caller for &mut P {
667    fn command(
668        &mut self,
669        iface: InterfaceNo,
670        ord: Ordinal,
671        args: &[u8],
672    ) -> Result<Correlation, SendError> {
673        (**self).command(iface, ord, args)
674    }
675    fn query(
676        &mut self,
677        iface: InterfaceNo,
678        ord: Ordinal,
679        args: &[u8],
680    ) -> Result<Correlation, SendError> {
681        (**self).query(iface, ord, args)
682    }
683    fn ack(&mut self, c: Correlation) -> Option<Result<(), CallError>> {
684        (**self).ack(c)
685    }
686    fn reply(
687        &mut self,
688        c: Correlation,
689        out: &mut [u8],
690    ) -> Result<Option<Result<usize, CallError>>, ReadError> {
691        (**self).reply(c, out)
692    }
693    fn forget(&mut self, c: Correlation) {
694        (**self).forget(c);
695    }
696}
697
698impl<P: Handler + ?Sized> Handler for &mut P {
699    fn serve(&mut self, iface: InterfaceNo, ords: &[Ordinal]) -> Result<(), ServeError> {
700        (**self).serve(iface, ords)
701    }
702    fn next_claim(&mut self, out: &mut [u8]) -> Result<Option<Claim>, ReadError> {
703        (**self).next_claim(out)
704    }
705    fn settle(
706        &mut self,
707        claim: ClaimId,
708        outcome: Result<&[u8], CallError>,
709    ) -> Result<(), SettleError> {
710        (**self).settle(claim, outcome)
711    }
712}
713
714impl<P: FixedReader + ?Sized> FixedReader for &P {
715    fn read_fixed(
716        &self,
717        iface: InterfaceNo,
718        ord: Ordinal,
719        out: &mut [u8],
720    ) -> Result<usize, ReadError> {
721        (**self).read_fixed(iface, ord, out)
722    }
723}
724
725impl<P: FixedReader + ?Sized> FixedReader for &mut P {
726    fn read_fixed(
727        &self,
728        iface: InterfaceNo,
729        ord: Ordinal,
730        out: &mut [u8],
731    ) -> Result<usize, ReadError> {
732        (**self).read_fixed(iface, ord, out)
733    }
734}
735
736impl<P: ScannableSignals + ?Sized> ScannableSignals for &P {
737    fn generation(&self, iface: InterfaceNo) -> u64 {
738        (**self).generation(iface)
739    }
740    fn scan(&self, marks: &mut [Watermark], out: &mut [Changed]) -> usize {
741        (**self).scan(marks, out)
742    }
743}
744
745impl<P: ScannableSignals + ?Sized> ScannableSignals for &mut P {
746    fn generation(&self, iface: InterfaceNo) -> u64 {
747        (**self).generation(iface)
748    }
749    fn scan(&self, marks: &mut [Watermark], out: &mut [Changed]) -> usize {
750        (**self).scan(marks, out)
751    }
752}
753
754impl<P: CoherentSignals + ?Sized> CoherentSignals for &P {
755    fn read_coherent(
756        &self,
757        iface: InterfaceNo,
758        ords: &[Ordinal],
759        out: &mut [u8],
760        samples: &mut [RawSample],
761    ) -> Result<usize, ReadError> {
762        (**self).read_coherent(iface, ords, out, samples)
763    }
764}
765
766impl<P: CoherentSignals + ?Sized> CoherentSignals for &mut P {
767    fn read_coherent(
768        &self,
769        iface: InterfaceNo,
770        ords: &[Ordinal],
771        out: &mut [u8],
772        samples: &mut [RawSample],
773    ) -> Result<usize, ReadError> {
774        (**self).read_coherent(iface, ords, out, samples)
775    }
776}
777
778impl<P: Wakeable + ?Sized> Wakeable for &P {
779    fn wake_on(&self, what: Interest, waker: &Waker) {
780        (**self).wake_on(what, waker);
781    }
782}
783
784impl<P: Wakeable + ?Sized> Wakeable for &mut P {
785    fn wake_on(&self, what: Interest, waker: &Waker) {
786        (**self).wake_on(what, waker);
787    }
788}