fidl_fuchsia_time_alarms/
fidl_fuchsia_time_alarms.rs

1// WARNING: This file is machine generated by fidlgen.
2
3#![warn(clippy::all)]
4#![allow(unused_parens, unused_mut, unused_imports, nonstandard_style)]
5
6use bitflags::bitflags;
7use fidl::client::QueryResponseFut;
8use fidl::encoding::{MessageBufFor, ProxyChannelBox, ResourceDialect};
9use fidl::endpoints::{ControlHandle as _, Responder as _};
10pub use fidl_fuchsia_time_alarms__common::*;
11use futures::future::{self, MaybeDone, TryFutureExt};
12use zx_status;
13
14#[derive(Debug, PartialEq)]
15pub struct SetAndWaitArgs {
16    /// The deadline at which the timer is supposed to fire. This
17    /// corresponds to a time instant on the boot timeline.
18    pub deadline: fidl::BootInstant,
19    /// Optional mode that allows the API to support a number of use cases.
20    pub mode: SetMode,
21    /// Set to a nonempty value to identify the alarm. A unique value
22    /// of [AlarmId] must be picked per each unique alarm within a
23    /// single FIDL connection's scope.
24    ///
25    /// Supplying an alarm_id for an already scheduled alarm reschedules
26    /// that alarm.
27    pub alarm_id: String,
28}
29
30impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect> for SetAndWaitArgs {}
31
32#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
33pub struct WakeAlarmsSetAndWaitResponse {
34    /// Used by the caller to ensure a minimum time slice for useful work,
35    /// before the system may suspend again.
36    pub keep_alive: fidl::EventPair,
37}
38
39impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
40    for WakeAlarmsSetAndWaitResponse
41{
42}
43
44#[derive(Debug)]
45pub enum SetMode {
46    /// This lease is dropped as immediately after the alarm is scheduled
47    /// (or an error occurs during scheduling), thus guaranteeing that the
48    /// alarm is scheduled before the system is suspended.
49    KeepAlive(fidl::EventPair),
50    /// The callee signals this event (with ZX_EVENT_SIGNALED) once the alarm
51    /// is scheduled. This indicates that the caller can drop any pending wake
52    /// leases related to this call.
53    NotifySetupDone(fidl::Event),
54    #[doc(hidden)]
55    __SourceBreaking { unknown_ordinal: u64 },
56}
57
58/// Pattern that matches an unknown `SetMode` member.
59#[macro_export]
60macro_rules! SetModeUnknown {
61    () => {
62        _
63    };
64}
65
66// Custom PartialEq so that unknown variants are not equal to themselves.
67impl PartialEq for SetMode {
68    fn eq(&self, other: &Self) -> bool {
69        match (self, other) {
70            (Self::KeepAlive(x), Self::KeepAlive(y)) => *x == *y,
71            (Self::NotifySetupDone(x), Self::NotifySetupDone(y)) => *x == *y,
72            _ => false,
73        }
74    }
75}
76
77impl SetMode {
78    #[inline]
79    pub fn ordinal(&self) -> u64 {
80        match *self {
81            Self::KeepAlive(_) => 1,
82            Self::NotifySetupDone(_) => 2,
83            Self::__SourceBreaking { unknown_ordinal } => unknown_ordinal,
84        }
85    }
86
87    #[inline]
88    pub fn unknown_variant_for_testing() -> Self {
89        Self::__SourceBreaking { unknown_ordinal: 0 }
90    }
91
92    #[inline]
93    pub fn is_unknown(&self) -> bool {
94        match self {
95            Self::__SourceBreaking { .. } => true,
96            _ => false,
97        }
98    }
99}
100
101impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect> for SetMode {}
102
103#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
104pub struct WakeAlarmsMarker;
105
106impl fidl::endpoints::ProtocolMarker for WakeAlarmsMarker {
107    type Proxy = WakeAlarmsProxy;
108    type RequestStream = WakeAlarmsRequestStream;
109    #[cfg(target_os = "fuchsia")]
110    type SynchronousProxy = WakeAlarmsSynchronousProxy;
111
112    const DEBUG_NAME: &'static str = "fuchsia.time.alarms.WakeAlarms";
113}
114impl fidl::endpoints::DiscoverableProtocolMarker for WakeAlarmsMarker {}
115pub type WakeAlarmsSetAndWaitResult = Result<fidl::EventPair, WakeAlarmsError>;
116
117pub trait WakeAlarmsProxyInterface: Send + Sync {
118    type SetAndWaitResponseFut: std::future::Future<Output = Result<WakeAlarmsSetAndWaitResult, fidl::Error>>
119        + Send;
120    fn r#set_and_wait(
121        &self,
122        deadline: fidl::BootInstant,
123        mode: SetMode,
124        alarm_id: &str,
125    ) -> Self::SetAndWaitResponseFut;
126    fn r#cancel(&self, alarm_id: &str) -> Result<(), fidl::Error>;
127}
128#[derive(Debug)]
129#[cfg(target_os = "fuchsia")]
130pub struct WakeAlarmsSynchronousProxy {
131    client: fidl::client::sync::Client,
132}
133
134#[cfg(target_os = "fuchsia")]
135impl fidl::endpoints::SynchronousProxy for WakeAlarmsSynchronousProxy {
136    type Proxy = WakeAlarmsProxy;
137    type Protocol = WakeAlarmsMarker;
138
139    fn from_channel(inner: fidl::Channel) -> Self {
140        Self::new(inner)
141    }
142
143    fn into_channel(self) -> fidl::Channel {
144        self.client.into_channel()
145    }
146
147    fn as_channel(&self) -> &fidl::Channel {
148        self.client.as_channel()
149    }
150}
151
152#[cfg(target_os = "fuchsia")]
153impl WakeAlarmsSynchronousProxy {
154    pub fn new(channel: fidl::Channel) -> Self {
155        let protocol_name = <WakeAlarmsMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
156        Self { client: fidl::client::sync::Client::new(channel, protocol_name) }
157    }
158
159    pub fn into_channel(self) -> fidl::Channel {
160        self.client.into_channel()
161    }
162
163    /// Waits until an event arrives and returns it. It is safe for other
164    /// threads to make concurrent requests while waiting for an event.
165    pub fn wait_for_event(
166        &self,
167        deadline: zx::MonotonicInstant,
168    ) -> Result<WakeAlarmsEvent, fidl::Error> {
169        WakeAlarmsEvent::decode(self.client.wait_for_event(deadline)?)
170    }
171
172    /// Sets a wake alarm with the provided parameters, and waits for the alarm
173    /// to fire.
174    ///
175    /// The caller may request multiple alarms concurrently. Re-requesting
176    /// an alarm that has the same `alarm_id` as an already scheduled alarm
177    /// causes that scheduled alarm to be canceled before the same alarm
178    /// is scheduled again.
179    ///
180    /// The call to `SetAndWait` returns when the alarm fires, or an error
181    /// occurs, or the alarm is canceled.
182    ///
183    /// ## Return value
184    ///
185    /// * `keep_alive`: a handle which prevents system suspend so long as
186    ///   it is held alive.
187    ///
188    /// ## Protocol Errors
189    ///
190    /// * [DROPPED] if the alarm has been canceled by using
191    ///   [Cancel].
192    /// * [UNSPECIFIED] you are observing a new failure mode which has not
193    ///   been assigned an error code yet. Expect this failure mode to be
194    ///   assigned a more specific error code in future versions of this API.
195    ///   This is not a bug, but an indication that you may need to update the
196    ///   API version.
197    /// * [INTERNAL] is a bug: an internal fallible call (which is expected
198    ///   to be unlikely to fail) has failed somehow. Please report this for
199    ///   investigation.
200    pub fn r#set_and_wait(
201        &self,
202        mut deadline: fidl::BootInstant,
203        mut mode: SetMode,
204        mut alarm_id: &str,
205        ___deadline: zx::MonotonicInstant,
206    ) -> Result<WakeAlarmsSetAndWaitResult, fidl::Error> {
207        let _response = self.client.send_query::<
208            SetAndWaitArgs,
209            fidl::encoding::FlexibleResultType<WakeAlarmsSetAndWaitResponse, WakeAlarmsError>,
210        >(
211            (deadline, &mut mode, alarm_id,),
212            0x57ebd075ce4beba,
213            fidl::encoding::DynamicFlags::FLEXIBLE,
214            ___deadline,
215        )?
216        .into_result::<WakeAlarmsMarker>("set_and_wait")?;
217        Ok(_response.map(|x| x.keep_alive))
218    }
219
220    /// Cancels the alarm specified by `alarm_id`.
221    ///
222    /// Providing an `alarm_id` of an alarm that is not scheduled quietly
223    /// succeeds.
224    pub fn r#cancel(&self, mut alarm_id: &str) -> Result<(), fidl::Error> {
225        self.client.send::<WakeAlarmsCancelRequest>(
226            (alarm_id,),
227            0x7b23a9760115e55c,
228            fidl::encoding::DynamicFlags::FLEXIBLE,
229        )
230    }
231}
232
233#[cfg(target_os = "fuchsia")]
234impl From<WakeAlarmsSynchronousProxy> for zx::Handle {
235    fn from(value: WakeAlarmsSynchronousProxy) -> Self {
236        value.into_channel().into()
237    }
238}
239
240#[cfg(target_os = "fuchsia")]
241impl From<fidl::Channel> for WakeAlarmsSynchronousProxy {
242    fn from(value: fidl::Channel) -> Self {
243        Self::new(value)
244    }
245}
246
247#[cfg(target_os = "fuchsia")]
248impl fidl::endpoints::FromClient for WakeAlarmsSynchronousProxy {
249    type Protocol = WakeAlarmsMarker;
250
251    fn from_client(value: fidl::endpoints::ClientEnd<WakeAlarmsMarker>) -> Self {
252        Self::new(value.into_channel())
253    }
254}
255
256#[derive(Debug, Clone)]
257pub struct WakeAlarmsProxy {
258    client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
259}
260
261impl fidl::endpoints::Proxy for WakeAlarmsProxy {
262    type Protocol = WakeAlarmsMarker;
263
264    fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
265        Self::new(inner)
266    }
267
268    fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
269        self.client.into_channel().map_err(|client| Self { client })
270    }
271
272    fn as_channel(&self) -> &::fidl::AsyncChannel {
273        self.client.as_channel()
274    }
275}
276
277impl WakeAlarmsProxy {
278    /// Create a new Proxy for fuchsia.time.alarms/WakeAlarms.
279    pub fn new(channel: ::fidl::AsyncChannel) -> Self {
280        let protocol_name = <WakeAlarmsMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
281        Self { client: fidl::client::Client::new(channel, protocol_name) }
282    }
283
284    /// Get a Stream of events from the remote end of the protocol.
285    ///
286    /// # Panics
287    ///
288    /// Panics if the event stream was already taken.
289    pub fn take_event_stream(&self) -> WakeAlarmsEventStream {
290        WakeAlarmsEventStream { event_receiver: self.client.take_event_receiver() }
291    }
292
293    /// Sets a wake alarm with the provided parameters, and waits for the alarm
294    /// to fire.
295    ///
296    /// The caller may request multiple alarms concurrently. Re-requesting
297    /// an alarm that has the same `alarm_id` as an already scheduled alarm
298    /// causes that scheduled alarm to be canceled before the same alarm
299    /// is scheduled again.
300    ///
301    /// The call to `SetAndWait` returns when the alarm fires, or an error
302    /// occurs, or the alarm is canceled.
303    ///
304    /// ## Return value
305    ///
306    /// * `keep_alive`: a handle which prevents system suspend so long as
307    ///   it is held alive.
308    ///
309    /// ## Protocol Errors
310    ///
311    /// * [DROPPED] if the alarm has been canceled by using
312    ///   [Cancel].
313    /// * [UNSPECIFIED] you are observing a new failure mode which has not
314    ///   been assigned an error code yet. Expect this failure mode to be
315    ///   assigned a more specific error code in future versions of this API.
316    ///   This is not a bug, but an indication that you may need to update the
317    ///   API version.
318    /// * [INTERNAL] is a bug: an internal fallible call (which is expected
319    ///   to be unlikely to fail) has failed somehow. Please report this for
320    ///   investigation.
321    pub fn r#set_and_wait(
322        &self,
323        mut deadline: fidl::BootInstant,
324        mut mode: SetMode,
325        mut alarm_id: &str,
326    ) -> fidl::client::QueryResponseFut<
327        WakeAlarmsSetAndWaitResult,
328        fidl::encoding::DefaultFuchsiaResourceDialect,
329    > {
330        WakeAlarmsProxyInterface::r#set_and_wait(self, deadline, mode, alarm_id)
331    }
332
333    /// Cancels the alarm specified by `alarm_id`.
334    ///
335    /// Providing an `alarm_id` of an alarm that is not scheduled quietly
336    /// succeeds.
337    pub fn r#cancel(&self, mut alarm_id: &str) -> Result<(), fidl::Error> {
338        WakeAlarmsProxyInterface::r#cancel(self, alarm_id)
339    }
340}
341
342impl WakeAlarmsProxyInterface for WakeAlarmsProxy {
343    type SetAndWaitResponseFut = fidl::client::QueryResponseFut<
344        WakeAlarmsSetAndWaitResult,
345        fidl::encoding::DefaultFuchsiaResourceDialect,
346    >;
347    fn r#set_and_wait(
348        &self,
349        mut deadline: fidl::BootInstant,
350        mut mode: SetMode,
351        mut alarm_id: &str,
352    ) -> Self::SetAndWaitResponseFut {
353        fn _decode(
354            mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
355        ) -> Result<WakeAlarmsSetAndWaitResult, fidl::Error> {
356            let _response = fidl::client::decode_transaction_body::<
357                fidl::encoding::FlexibleResultType<WakeAlarmsSetAndWaitResponse, WakeAlarmsError>,
358                fidl::encoding::DefaultFuchsiaResourceDialect,
359                0x57ebd075ce4beba,
360            >(_buf?)?
361            .into_result::<WakeAlarmsMarker>("set_and_wait")?;
362            Ok(_response.map(|x| x.keep_alive))
363        }
364        self.client.send_query_and_decode::<SetAndWaitArgs, WakeAlarmsSetAndWaitResult>(
365            (deadline, &mut mode, alarm_id),
366            0x57ebd075ce4beba,
367            fidl::encoding::DynamicFlags::FLEXIBLE,
368            _decode,
369        )
370    }
371
372    fn r#cancel(&self, mut alarm_id: &str) -> Result<(), fidl::Error> {
373        self.client.send::<WakeAlarmsCancelRequest>(
374            (alarm_id,),
375            0x7b23a9760115e55c,
376            fidl::encoding::DynamicFlags::FLEXIBLE,
377        )
378    }
379}
380
381pub struct WakeAlarmsEventStream {
382    event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
383}
384
385impl std::marker::Unpin for WakeAlarmsEventStream {}
386
387impl futures::stream::FusedStream for WakeAlarmsEventStream {
388    fn is_terminated(&self) -> bool {
389        self.event_receiver.is_terminated()
390    }
391}
392
393impl futures::Stream for WakeAlarmsEventStream {
394    type Item = Result<WakeAlarmsEvent, fidl::Error>;
395
396    fn poll_next(
397        mut self: std::pin::Pin<&mut Self>,
398        cx: &mut std::task::Context<'_>,
399    ) -> std::task::Poll<Option<Self::Item>> {
400        match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
401            &mut self.event_receiver,
402            cx
403        )?) {
404            Some(buf) => std::task::Poll::Ready(Some(WakeAlarmsEvent::decode(buf))),
405            None => std::task::Poll::Ready(None),
406        }
407    }
408}
409
410#[derive(Debug)]
411pub enum WakeAlarmsEvent {
412    #[non_exhaustive]
413    _UnknownEvent {
414        /// Ordinal of the event that was sent.
415        ordinal: u64,
416    },
417}
418
419impl WakeAlarmsEvent {
420    /// Decodes a message buffer as a [`WakeAlarmsEvent`].
421    fn decode(
422        mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
423    ) -> Result<WakeAlarmsEvent, fidl::Error> {
424        let (bytes, _handles) = buf.split_mut();
425        let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
426        debug_assert_eq!(tx_header.tx_id, 0);
427        match tx_header.ordinal {
428            _ if tx_header.dynamic_flags().contains(fidl::encoding::DynamicFlags::FLEXIBLE) => {
429                Ok(WakeAlarmsEvent::_UnknownEvent { ordinal: tx_header.ordinal })
430            }
431            _ => Err(fidl::Error::UnknownOrdinal {
432                ordinal: tx_header.ordinal,
433                protocol_name: <WakeAlarmsMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
434            }),
435        }
436    }
437}
438
439/// A Stream of incoming requests for fuchsia.time.alarms/WakeAlarms.
440pub struct WakeAlarmsRequestStream {
441    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
442    is_terminated: bool,
443}
444
445impl std::marker::Unpin for WakeAlarmsRequestStream {}
446
447impl futures::stream::FusedStream for WakeAlarmsRequestStream {
448    fn is_terminated(&self) -> bool {
449        self.is_terminated
450    }
451}
452
453impl fidl::endpoints::RequestStream for WakeAlarmsRequestStream {
454    type Protocol = WakeAlarmsMarker;
455    type ControlHandle = WakeAlarmsControlHandle;
456
457    fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
458        Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
459    }
460
461    fn control_handle(&self) -> Self::ControlHandle {
462        WakeAlarmsControlHandle { inner: self.inner.clone() }
463    }
464
465    fn into_inner(
466        self,
467    ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
468    {
469        (self.inner, self.is_terminated)
470    }
471
472    fn from_inner(
473        inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
474        is_terminated: bool,
475    ) -> Self {
476        Self { inner, is_terminated }
477    }
478}
479
480impl futures::Stream for WakeAlarmsRequestStream {
481    type Item = Result<WakeAlarmsRequest, fidl::Error>;
482
483    fn poll_next(
484        mut self: std::pin::Pin<&mut Self>,
485        cx: &mut std::task::Context<'_>,
486    ) -> std::task::Poll<Option<Self::Item>> {
487        let this = &mut *self;
488        if this.inner.check_shutdown(cx) {
489            this.is_terminated = true;
490            return std::task::Poll::Ready(None);
491        }
492        if this.is_terminated {
493            panic!("polled WakeAlarmsRequestStream after completion");
494        }
495        fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
496            |bytes, handles| {
497                match this.inner.channel().read_etc(cx, bytes, handles) {
498                    std::task::Poll::Ready(Ok(())) => {}
499                    std::task::Poll::Pending => return std::task::Poll::Pending,
500                    std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
501                        this.is_terminated = true;
502                        return std::task::Poll::Ready(None);
503                    }
504                    std::task::Poll::Ready(Err(e)) => {
505                        return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
506                            e.into(),
507                        ))))
508                    }
509                }
510
511                // A message has been received from the channel
512                let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
513
514                std::task::Poll::Ready(Some(match header.ordinal {
515                    0x57ebd075ce4beba => {
516                        header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
517                        let mut req = fidl::new_empty!(
518                            SetAndWaitArgs,
519                            fidl::encoding::DefaultFuchsiaResourceDialect
520                        );
521                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<SetAndWaitArgs>(&header, _body_bytes, handles, &mut req)?;
522                        let control_handle = WakeAlarmsControlHandle { inner: this.inner.clone() };
523                        Ok(WakeAlarmsRequest::SetAndWait {
524                            deadline: req.deadline,
525                            mode: req.mode,
526                            alarm_id: req.alarm_id,
527
528                            responder: WakeAlarmsSetAndWaitResponder {
529                                control_handle: std::mem::ManuallyDrop::new(control_handle),
530                                tx_id: header.tx_id,
531                            },
532                        })
533                    }
534                    0x7b23a9760115e55c => {
535                        header.validate_request_tx_id(fidl::MethodType::OneWay)?;
536                        let mut req = fidl::new_empty!(
537                            WakeAlarmsCancelRequest,
538                            fidl::encoding::DefaultFuchsiaResourceDialect
539                        );
540                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<WakeAlarmsCancelRequest>(&header, _body_bytes, handles, &mut req)?;
541                        let control_handle = WakeAlarmsControlHandle { inner: this.inner.clone() };
542                        Ok(WakeAlarmsRequest::Cancel { alarm_id: req.alarm_id, control_handle })
543                    }
544                    _ if header.tx_id == 0
545                        && header
546                            .dynamic_flags()
547                            .contains(fidl::encoding::DynamicFlags::FLEXIBLE) =>
548                    {
549                        Ok(WakeAlarmsRequest::_UnknownMethod {
550                            ordinal: header.ordinal,
551                            control_handle: WakeAlarmsControlHandle { inner: this.inner.clone() },
552                            method_type: fidl::MethodType::OneWay,
553                        })
554                    }
555                    _ if header
556                        .dynamic_flags()
557                        .contains(fidl::encoding::DynamicFlags::FLEXIBLE) =>
558                    {
559                        this.inner.send_framework_err(
560                            fidl::encoding::FrameworkErr::UnknownMethod,
561                            header.tx_id,
562                            header.ordinal,
563                            header.dynamic_flags(),
564                            (bytes, handles),
565                        )?;
566                        Ok(WakeAlarmsRequest::_UnknownMethod {
567                            ordinal: header.ordinal,
568                            control_handle: WakeAlarmsControlHandle { inner: this.inner.clone() },
569                            method_type: fidl::MethodType::TwoWay,
570                        })
571                    }
572                    _ => Err(fidl::Error::UnknownOrdinal {
573                        ordinal: header.ordinal,
574                        protocol_name:
575                            <WakeAlarmsMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
576                    }),
577                }))
578            },
579        )
580    }
581}
582
583/// [WakeAlarms] provides setting up platform-wide wake alarms.
584///
585/// An alarm is a promise made by the system to the caller of the API to notify
586/// the caller that AT LEAST a certain amount of time has expired. The alarm
587/// may fire later than the requested amount of time at the discretion of the
588/// server implementing this API.
589///
590/// When this notification happens, we say that the wake alarm has "fired".
591///
592/// A "wake" alarm firing also ensures that the system comes back from a reduced
593/// power state if needed, so that it can notify the caller.
594///
595/// The general shape of a wake alarm API has three parts:
596/// * A specification of when a wake alarm is supposed to fire,
597/// * A way to notify the caller of an alarm that fired, and
598/// * A way to keep the system awake until both the caller and the callee have
599///   completed work associated with the alarm.
600#[derive(Debug)]
601pub enum WakeAlarmsRequest {
602    /// Sets a wake alarm with the provided parameters, and waits for the alarm
603    /// to fire.
604    ///
605    /// The caller may request multiple alarms concurrently. Re-requesting
606    /// an alarm that has the same `alarm_id` as an already scheduled alarm
607    /// causes that scheduled alarm to be canceled before the same alarm
608    /// is scheduled again.
609    ///
610    /// The call to `SetAndWait` returns when the alarm fires, or an error
611    /// occurs, or the alarm is canceled.
612    ///
613    /// ## Return value
614    ///
615    /// * `keep_alive`: a handle which prevents system suspend so long as
616    ///   it is held alive.
617    ///
618    /// ## Protocol Errors
619    ///
620    /// * [DROPPED] if the alarm has been canceled by using
621    ///   [Cancel].
622    /// * [UNSPECIFIED] you are observing a new failure mode which has not
623    ///   been assigned an error code yet. Expect this failure mode to be
624    ///   assigned a more specific error code in future versions of this API.
625    ///   This is not a bug, but an indication that you may need to update the
626    ///   API version.
627    /// * [INTERNAL] is a bug: an internal fallible call (which is expected
628    ///   to be unlikely to fail) has failed somehow. Please report this for
629    ///   investigation.
630    SetAndWait {
631        deadline: fidl::BootInstant,
632        mode: SetMode,
633        alarm_id: String,
634        responder: WakeAlarmsSetAndWaitResponder,
635    },
636    /// Cancels the alarm specified by `alarm_id`.
637    ///
638    /// Providing an `alarm_id` of an alarm that is not scheduled quietly
639    /// succeeds.
640    Cancel { alarm_id: String, control_handle: WakeAlarmsControlHandle },
641    /// An interaction was received which does not match any known method.
642    #[non_exhaustive]
643    _UnknownMethod {
644        /// Ordinal of the method that was called.
645        ordinal: u64,
646        control_handle: WakeAlarmsControlHandle,
647        method_type: fidl::MethodType,
648    },
649}
650
651impl WakeAlarmsRequest {
652    #[allow(irrefutable_let_patterns)]
653    pub fn into_set_and_wait(
654        self,
655    ) -> Option<(fidl::BootInstant, SetMode, String, WakeAlarmsSetAndWaitResponder)> {
656        if let WakeAlarmsRequest::SetAndWait { deadline, mode, alarm_id, responder } = self {
657            Some((deadline, mode, alarm_id, responder))
658        } else {
659            None
660        }
661    }
662
663    #[allow(irrefutable_let_patterns)]
664    pub fn into_cancel(self) -> Option<(String, WakeAlarmsControlHandle)> {
665        if let WakeAlarmsRequest::Cancel { alarm_id, control_handle } = self {
666            Some((alarm_id, control_handle))
667        } else {
668            None
669        }
670    }
671
672    /// Name of the method defined in FIDL
673    pub fn method_name(&self) -> &'static str {
674        match *self {
675            WakeAlarmsRequest::SetAndWait { .. } => "set_and_wait",
676            WakeAlarmsRequest::Cancel { .. } => "cancel",
677            WakeAlarmsRequest::_UnknownMethod { method_type: fidl::MethodType::OneWay, .. } => {
678                "unknown one-way method"
679            }
680            WakeAlarmsRequest::_UnknownMethod { method_type: fidl::MethodType::TwoWay, .. } => {
681                "unknown two-way method"
682            }
683        }
684    }
685}
686
687#[derive(Debug, Clone)]
688pub struct WakeAlarmsControlHandle {
689    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
690}
691
692impl fidl::endpoints::ControlHandle for WakeAlarmsControlHandle {
693    fn shutdown(&self) {
694        self.inner.shutdown()
695    }
696    fn shutdown_with_epitaph(&self, status: zx_status::Status) {
697        self.inner.shutdown_with_epitaph(status)
698    }
699
700    fn is_closed(&self) -> bool {
701        self.inner.channel().is_closed()
702    }
703    fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
704        self.inner.channel().on_closed()
705    }
706
707    #[cfg(target_os = "fuchsia")]
708    fn signal_peer(
709        &self,
710        clear_mask: zx::Signals,
711        set_mask: zx::Signals,
712    ) -> Result<(), zx_status::Status> {
713        use fidl::Peered;
714        self.inner.channel().signal_peer(clear_mask, set_mask)
715    }
716}
717
718impl WakeAlarmsControlHandle {}
719
720#[must_use = "FIDL methods require a response to be sent"]
721#[derive(Debug)]
722pub struct WakeAlarmsSetAndWaitResponder {
723    control_handle: std::mem::ManuallyDrop<WakeAlarmsControlHandle>,
724    tx_id: u32,
725}
726
727/// Set the the channel to be shutdown (see [`WakeAlarmsControlHandle::shutdown`])
728/// if the responder is dropped without sending a response, so that the client
729/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
730impl std::ops::Drop for WakeAlarmsSetAndWaitResponder {
731    fn drop(&mut self) {
732        self.control_handle.shutdown();
733        // Safety: drops once, never accessed again
734        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
735    }
736}
737
738impl fidl::endpoints::Responder for WakeAlarmsSetAndWaitResponder {
739    type ControlHandle = WakeAlarmsControlHandle;
740
741    fn control_handle(&self) -> &WakeAlarmsControlHandle {
742        &self.control_handle
743    }
744
745    fn drop_without_shutdown(mut self) {
746        // Safety: drops once, never accessed again due to mem::forget
747        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
748        // Prevent Drop from running (which would shut down the channel)
749        std::mem::forget(self);
750    }
751}
752
753impl WakeAlarmsSetAndWaitResponder {
754    /// Sends a response to the FIDL transaction.
755    ///
756    /// Sets the channel to shutdown if an error occurs.
757    pub fn send(
758        self,
759        mut result: Result<fidl::EventPair, WakeAlarmsError>,
760    ) -> Result<(), fidl::Error> {
761        let _result = self.send_raw(result);
762        if _result.is_err() {
763            self.control_handle.shutdown();
764        }
765        self.drop_without_shutdown();
766        _result
767    }
768
769    /// Similar to "send" but does not shutdown the channel if an error occurs.
770    pub fn send_no_shutdown_on_err(
771        self,
772        mut result: Result<fidl::EventPair, WakeAlarmsError>,
773    ) -> Result<(), fidl::Error> {
774        let _result = self.send_raw(result);
775        self.drop_without_shutdown();
776        _result
777    }
778
779    fn send_raw(
780        &self,
781        mut result: Result<fidl::EventPair, WakeAlarmsError>,
782    ) -> Result<(), fidl::Error> {
783        self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
784            WakeAlarmsSetAndWaitResponse,
785            WakeAlarmsError,
786        >>(
787            fidl::encoding::FlexibleResult::new(result.map(|keep_alive| (keep_alive,))),
788            self.tx_id,
789            0x57ebd075ce4beba,
790            fidl::encoding::DynamicFlags::FLEXIBLE,
791        )
792    }
793}
794
795mod internal {
796    use super::*;
797
798    impl fidl::encoding::ResourceTypeMarker for SetAndWaitArgs {
799        type Borrowed<'a> = &'a mut Self;
800        fn take_or_borrow<'a>(
801            value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
802        ) -> Self::Borrowed<'a> {
803            value
804        }
805    }
806
807    unsafe impl fidl::encoding::TypeMarker for SetAndWaitArgs {
808        type Owned = Self;
809
810        #[inline(always)]
811        fn inline_align(_context: fidl::encoding::Context) -> usize {
812            8
813        }
814
815        #[inline(always)]
816        fn inline_size(_context: fidl::encoding::Context) -> usize {
817            40
818        }
819    }
820
821    unsafe impl
822        fidl::encoding::Encode<SetAndWaitArgs, fidl::encoding::DefaultFuchsiaResourceDialect>
823        for &mut SetAndWaitArgs
824    {
825        #[inline]
826        unsafe fn encode(
827            self,
828            encoder: &mut fidl::encoding::Encoder<
829                '_,
830                fidl::encoding::DefaultFuchsiaResourceDialect,
831            >,
832            offset: usize,
833            _depth: fidl::encoding::Depth,
834        ) -> fidl::Result<()> {
835            encoder.debug_check_bounds::<SetAndWaitArgs>(offset);
836            // Delegate to tuple encoding.
837            fidl::encoding::Encode::<SetAndWaitArgs, fidl::encoding::DefaultFuchsiaResourceDialect>::encode(
838                (
839                    <fidl::BootInstant as fidl::encoding::ValueTypeMarker>::borrow(&self.deadline),
840                    <SetMode as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.mode),
841                    <fidl::encoding::BoundedString<128> as fidl::encoding::ValueTypeMarker>::borrow(&self.alarm_id),
842                ),
843                encoder, offset, _depth
844            )
845        }
846    }
847    unsafe impl<
848            T0: fidl::encoding::Encode<
849                fidl::BootInstant,
850                fidl::encoding::DefaultFuchsiaResourceDialect,
851            >,
852            T1: fidl::encoding::Encode<SetMode, fidl::encoding::DefaultFuchsiaResourceDialect>,
853            T2: fidl::encoding::Encode<
854                fidl::encoding::BoundedString<128>,
855                fidl::encoding::DefaultFuchsiaResourceDialect,
856            >,
857        > fidl::encoding::Encode<SetAndWaitArgs, fidl::encoding::DefaultFuchsiaResourceDialect>
858        for (T0, T1, T2)
859    {
860        #[inline]
861        unsafe fn encode(
862            self,
863            encoder: &mut fidl::encoding::Encoder<
864                '_,
865                fidl::encoding::DefaultFuchsiaResourceDialect,
866            >,
867            offset: usize,
868            depth: fidl::encoding::Depth,
869        ) -> fidl::Result<()> {
870            encoder.debug_check_bounds::<SetAndWaitArgs>(offset);
871            // Zero out padding regions. There's no need to apply masks
872            // because the unmasked parts will be overwritten by fields.
873            // Write the fields.
874            self.0.encode(encoder, offset + 0, depth)?;
875            self.1.encode(encoder, offset + 8, depth)?;
876            self.2.encode(encoder, offset + 24, depth)?;
877            Ok(())
878        }
879    }
880
881    impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
882        for SetAndWaitArgs
883    {
884        #[inline(always)]
885        fn new_empty() -> Self {
886            Self {
887                deadline: fidl::new_empty!(
888                    fidl::BootInstant,
889                    fidl::encoding::DefaultFuchsiaResourceDialect
890                ),
891                mode: fidl::new_empty!(SetMode, fidl::encoding::DefaultFuchsiaResourceDialect),
892                alarm_id: fidl::new_empty!(
893                    fidl::encoding::BoundedString<128>,
894                    fidl::encoding::DefaultFuchsiaResourceDialect
895                ),
896            }
897        }
898
899        #[inline]
900        unsafe fn decode(
901            &mut self,
902            decoder: &mut fidl::encoding::Decoder<
903                '_,
904                fidl::encoding::DefaultFuchsiaResourceDialect,
905            >,
906            offset: usize,
907            _depth: fidl::encoding::Depth,
908        ) -> fidl::Result<()> {
909            decoder.debug_check_bounds::<Self>(offset);
910            // Verify that padding bytes are zero.
911            fidl::decode!(
912                fidl::BootInstant,
913                fidl::encoding::DefaultFuchsiaResourceDialect,
914                &mut self.deadline,
915                decoder,
916                offset + 0,
917                _depth
918            )?;
919            fidl::decode!(
920                SetMode,
921                fidl::encoding::DefaultFuchsiaResourceDialect,
922                &mut self.mode,
923                decoder,
924                offset + 8,
925                _depth
926            )?;
927            fidl::decode!(
928                fidl::encoding::BoundedString<128>,
929                fidl::encoding::DefaultFuchsiaResourceDialect,
930                &mut self.alarm_id,
931                decoder,
932                offset + 24,
933                _depth
934            )?;
935            Ok(())
936        }
937    }
938
939    impl fidl::encoding::ResourceTypeMarker for WakeAlarmsSetAndWaitResponse {
940        type Borrowed<'a> = &'a mut Self;
941        fn take_or_borrow<'a>(
942            value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
943        ) -> Self::Borrowed<'a> {
944            value
945        }
946    }
947
948    unsafe impl fidl::encoding::TypeMarker for WakeAlarmsSetAndWaitResponse {
949        type Owned = Self;
950
951        #[inline(always)]
952        fn inline_align(_context: fidl::encoding::Context) -> usize {
953            4
954        }
955
956        #[inline(always)]
957        fn inline_size(_context: fidl::encoding::Context) -> usize {
958            4
959        }
960    }
961
962    unsafe impl
963        fidl::encoding::Encode<
964            WakeAlarmsSetAndWaitResponse,
965            fidl::encoding::DefaultFuchsiaResourceDialect,
966        > for &mut WakeAlarmsSetAndWaitResponse
967    {
968        #[inline]
969        unsafe fn encode(
970            self,
971            encoder: &mut fidl::encoding::Encoder<
972                '_,
973                fidl::encoding::DefaultFuchsiaResourceDialect,
974            >,
975            offset: usize,
976            _depth: fidl::encoding::Depth,
977        ) -> fidl::Result<()> {
978            encoder.debug_check_bounds::<WakeAlarmsSetAndWaitResponse>(offset);
979            // Delegate to tuple encoding.
980            fidl::encoding::Encode::<
981                WakeAlarmsSetAndWaitResponse,
982                fidl::encoding::DefaultFuchsiaResourceDialect,
983            >::encode(
984                (<fidl::encoding::HandleType<
985                    fidl::EventPair,
986                    { fidl::ObjectType::EVENTPAIR.into_raw() },
987                    16387,
988                > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
989                    &mut self.keep_alive
990                ),),
991                encoder,
992                offset,
993                _depth,
994            )
995        }
996    }
997    unsafe impl<
998            T0: fidl::encoding::Encode<
999                fidl::encoding::HandleType<
1000                    fidl::EventPair,
1001                    { fidl::ObjectType::EVENTPAIR.into_raw() },
1002                    16387,
1003                >,
1004                fidl::encoding::DefaultFuchsiaResourceDialect,
1005            >,
1006        >
1007        fidl::encoding::Encode<
1008            WakeAlarmsSetAndWaitResponse,
1009            fidl::encoding::DefaultFuchsiaResourceDialect,
1010        > for (T0,)
1011    {
1012        #[inline]
1013        unsafe fn encode(
1014            self,
1015            encoder: &mut fidl::encoding::Encoder<
1016                '_,
1017                fidl::encoding::DefaultFuchsiaResourceDialect,
1018            >,
1019            offset: usize,
1020            depth: fidl::encoding::Depth,
1021        ) -> fidl::Result<()> {
1022            encoder.debug_check_bounds::<WakeAlarmsSetAndWaitResponse>(offset);
1023            // Zero out padding regions. There's no need to apply masks
1024            // because the unmasked parts will be overwritten by fields.
1025            // Write the fields.
1026            self.0.encode(encoder, offset + 0, depth)?;
1027            Ok(())
1028        }
1029    }
1030
1031    impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
1032        for WakeAlarmsSetAndWaitResponse
1033    {
1034        #[inline(always)]
1035        fn new_empty() -> Self {
1036            Self {
1037                keep_alive: fidl::new_empty!(fidl::encoding::HandleType<fidl::EventPair, { fidl::ObjectType::EVENTPAIR.into_raw() }, 16387>, fidl::encoding::DefaultFuchsiaResourceDialect),
1038            }
1039        }
1040
1041        #[inline]
1042        unsafe fn decode(
1043            &mut self,
1044            decoder: &mut fidl::encoding::Decoder<
1045                '_,
1046                fidl::encoding::DefaultFuchsiaResourceDialect,
1047            >,
1048            offset: usize,
1049            _depth: fidl::encoding::Depth,
1050        ) -> fidl::Result<()> {
1051            decoder.debug_check_bounds::<Self>(offset);
1052            // Verify that padding bytes are zero.
1053            fidl::decode!(fidl::encoding::HandleType<fidl::EventPair, { fidl::ObjectType::EVENTPAIR.into_raw() }, 16387>, fidl::encoding::DefaultFuchsiaResourceDialect, &mut self.keep_alive, decoder, offset + 0, _depth)?;
1054            Ok(())
1055        }
1056    }
1057
1058    impl fidl::encoding::ResourceTypeMarker for SetMode {
1059        type Borrowed<'a> = &'a mut Self;
1060        fn take_or_borrow<'a>(
1061            value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
1062        ) -> Self::Borrowed<'a> {
1063            value
1064        }
1065    }
1066
1067    unsafe impl fidl::encoding::TypeMarker for SetMode {
1068        type Owned = Self;
1069
1070        #[inline(always)]
1071        fn inline_align(_context: fidl::encoding::Context) -> usize {
1072            8
1073        }
1074
1075        #[inline(always)]
1076        fn inline_size(_context: fidl::encoding::Context) -> usize {
1077            16
1078        }
1079    }
1080
1081    unsafe impl fidl::encoding::Encode<SetMode, fidl::encoding::DefaultFuchsiaResourceDialect>
1082        for &mut SetMode
1083    {
1084        #[inline]
1085        unsafe fn encode(
1086            self,
1087            encoder: &mut fidl::encoding::Encoder<
1088                '_,
1089                fidl::encoding::DefaultFuchsiaResourceDialect,
1090            >,
1091            offset: usize,
1092            _depth: fidl::encoding::Depth,
1093        ) -> fidl::Result<()> {
1094            encoder.debug_check_bounds::<SetMode>(offset);
1095            encoder.write_num::<u64>(self.ordinal(), offset);
1096            match self {
1097                SetMode::KeepAlive(ref mut val) => fidl::encoding::encode_in_envelope::<
1098                    fidl::encoding::HandleType<
1099                        fidl::EventPair,
1100                        { fidl::ObjectType::EVENTPAIR.into_raw() },
1101                        16387,
1102                    >,
1103                    fidl::encoding::DefaultFuchsiaResourceDialect,
1104                >(
1105                    <fidl::encoding::HandleType<
1106                        fidl::EventPair,
1107                        { fidl::ObjectType::EVENTPAIR.into_raw() },
1108                        16387,
1109                    > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
1110                        val
1111                    ),
1112                    encoder,
1113                    offset + 8,
1114                    _depth,
1115                ),
1116                SetMode::NotifySetupDone(ref mut val) => fidl::encoding::encode_in_envelope::<
1117                    fidl::encoding::HandleType<
1118                        fidl::Event,
1119                        { fidl::ObjectType::EVENT.into_raw() },
1120                        2147483648,
1121                    >,
1122                    fidl::encoding::DefaultFuchsiaResourceDialect,
1123                >(
1124                    <fidl::encoding::HandleType<
1125                        fidl::Event,
1126                        { fidl::ObjectType::EVENT.into_raw() },
1127                        2147483648,
1128                    > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
1129                        val
1130                    ),
1131                    encoder,
1132                    offset + 8,
1133                    _depth,
1134                ),
1135                SetMode::__SourceBreaking { .. } => Err(fidl::Error::UnknownUnionTag),
1136            }
1137        }
1138    }
1139
1140    impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect> for SetMode {
1141        #[inline(always)]
1142        fn new_empty() -> Self {
1143            Self::__SourceBreaking { unknown_ordinal: 0 }
1144        }
1145
1146        #[inline]
1147        unsafe fn decode(
1148            &mut self,
1149            decoder: &mut fidl::encoding::Decoder<
1150                '_,
1151                fidl::encoding::DefaultFuchsiaResourceDialect,
1152            >,
1153            offset: usize,
1154            mut depth: fidl::encoding::Depth,
1155        ) -> fidl::Result<()> {
1156            decoder.debug_check_bounds::<Self>(offset);
1157            #[allow(unused_variables)]
1158            let next_out_of_line = decoder.next_out_of_line();
1159            let handles_before = decoder.remaining_handles();
1160            let (ordinal, inlined, num_bytes, num_handles) =
1161                fidl::encoding::decode_union_inline_portion(decoder, offset)?;
1162
1163            let member_inline_size = match ordinal {
1164                1 => <fidl::encoding::HandleType<
1165                    fidl::EventPair,
1166                    { fidl::ObjectType::EVENTPAIR.into_raw() },
1167                    16387,
1168                > as fidl::encoding::TypeMarker>::inline_size(decoder.context),
1169                2 => <fidl::encoding::HandleType<
1170                    fidl::Event,
1171                    { fidl::ObjectType::EVENT.into_raw() },
1172                    2147483648,
1173                > as fidl::encoding::TypeMarker>::inline_size(decoder.context),
1174                0 => return Err(fidl::Error::UnknownUnionTag),
1175                _ => num_bytes as usize,
1176            };
1177
1178            if inlined != (member_inline_size <= 4) {
1179                return Err(fidl::Error::InvalidInlineBitInEnvelope);
1180            }
1181            let _inner_offset;
1182            if inlined {
1183                decoder.check_inline_envelope_padding(offset + 8, member_inline_size)?;
1184                _inner_offset = offset + 8;
1185            } else {
1186                depth.increment()?;
1187                _inner_offset = decoder.out_of_line_offset(member_inline_size)?;
1188            }
1189            match ordinal {
1190                1 => {
1191                    #[allow(irrefutable_let_patterns)]
1192                    if let SetMode::KeepAlive(_) = self {
1193                        // Do nothing, read the value into the object
1194                    } else {
1195                        // Initialize `self` to the right variant
1196                        *self = SetMode::KeepAlive(
1197                            fidl::new_empty!(fidl::encoding::HandleType<fidl::EventPair, { fidl::ObjectType::EVENTPAIR.into_raw() }, 16387>, fidl::encoding::DefaultFuchsiaResourceDialect),
1198                        );
1199                    }
1200                    #[allow(irrefutable_let_patterns)]
1201                    if let SetMode::KeepAlive(ref mut val) = self {
1202                        fidl::decode!(fidl::encoding::HandleType<fidl::EventPair, { fidl::ObjectType::EVENTPAIR.into_raw() }, 16387>, fidl::encoding::DefaultFuchsiaResourceDialect, val, decoder, _inner_offset, depth)?;
1203                    } else {
1204                        unreachable!()
1205                    }
1206                }
1207                2 => {
1208                    #[allow(irrefutable_let_patterns)]
1209                    if let SetMode::NotifySetupDone(_) = self {
1210                        // Do nothing, read the value into the object
1211                    } else {
1212                        // Initialize `self` to the right variant
1213                        *self = SetMode::NotifySetupDone(
1214                            fidl::new_empty!(fidl::encoding::HandleType<fidl::Event, { fidl::ObjectType::EVENT.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect),
1215                        );
1216                    }
1217                    #[allow(irrefutable_let_patterns)]
1218                    if let SetMode::NotifySetupDone(ref mut val) = self {
1219                        fidl::decode!(fidl::encoding::HandleType<fidl::Event, { fidl::ObjectType::EVENT.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, val, decoder, _inner_offset, depth)?;
1220                    } else {
1221                        unreachable!()
1222                    }
1223                }
1224                #[allow(deprecated)]
1225                ordinal => {
1226                    for _ in 0..num_handles {
1227                        decoder.drop_next_handle()?;
1228                    }
1229                    *self = SetMode::__SourceBreaking { unknown_ordinal: ordinal };
1230                }
1231            }
1232            if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize) {
1233                return Err(fidl::Error::InvalidNumBytesInEnvelope);
1234            }
1235            if handles_before != decoder.remaining_handles() + (num_handles as usize) {
1236                return Err(fidl::Error::InvalidNumHandlesInEnvelope);
1237            }
1238            Ok(())
1239        }
1240    }
1241}