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}