Skip to main content

fidl_fuchsia_process_lifecycle/
fidl_fuchsia_process_lifecycle.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_process_lifecycle_common::*;
11use futures::future::{self, MaybeDone, TryFutureExt};
12use zx_status;
13
14#[derive(Debug, Default, PartialEq)]
15pub struct LifecycleOnEscrowRequest {
16    /// Escrow the outgoing directory server endpoint. Whenever the
17    /// component is started again, this will be returned as the
18    /// `PA_DIRECTORY_REQUEST` processargs entry.
19    pub outgoing_dir: Option<fidl::endpoints::ServerEnd<fidl_fuchsia_io::DirectoryMarker>>,
20    /// Escrow some user defined state. Whenever the component is started
21    /// again, this will be returned as the `PA_ESCROWED_DICTIONARY`
22    /// processargs entry.
23    ///
24    /// The framework will not wait for any signals on these objects.
25    ///
26    /// ## Example
27    ///
28    /// Let's say a component needs to escrow an event pair that represents
29    /// the result of some expensive calculation. It can create a
30    /// dictionary, put the event pair inside with an appropriate key
31    /// (e.g. `"my_event_pair"`), then check for that entry on startup.
32    /// Note that this is deprecated, please use
33    /// `escrowed_dictionary_handle` instead.
34    pub escrowed_dictionary: Option<fidl_fuchsia_component_sandbox::DictionaryRef>,
35    /// Escrow some user defined state. Whenever the component is started
36    /// again, this will be returned as the `PA_ESCROWED_DICTIONARY`
37    /// processargs entry.
38    ///
39    /// The framework will not wait for any signals on these objects.
40    ///
41    /// ## Example
42    ///
43    /// Let's say a component needs to escrow an event pair that represents
44    /// the result of some expensive calculation. It can create a
45    /// dictionary, put the event pair inside with an appropriate key
46    /// (e.g. `"my_event_pair"`), then check for that entry on startup.
47    pub escrowed_dictionary_handle: Option<fidl::EventPair>,
48    /// Recoverable bytes when this component stops running. Used to track
49    /// how much memory is saved when a component is escrowed, which is only
50    /// used for development purposes.
51    pub recoverable_bytes: Option<u64>,
52    #[doc(hidden)]
53    pub __source_breaking: fidl::marker::SourceBreaking,
54}
55
56impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect> for LifecycleOnEscrowRequest {}
57
58#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
59pub struct LifecycleMarker;
60
61impl fidl::endpoints::ProtocolMarker for LifecycleMarker {
62    type Proxy = LifecycleProxy;
63    type RequestStream = LifecycleRequestStream;
64    #[cfg(target_os = "fuchsia")]
65    type SynchronousProxy = LifecycleSynchronousProxy;
66
67    const DEBUG_NAME: &'static str = "(anonymous) Lifecycle";
68}
69
70pub trait LifecycleProxyInterface: Send + Sync {
71    fn r#stop(&self) -> Result<(), fidl::Error>;
72}
73#[derive(Debug)]
74#[cfg(target_os = "fuchsia")]
75pub struct LifecycleSynchronousProxy {
76    client: fidl::client::sync::Client,
77}
78
79#[cfg(target_os = "fuchsia")]
80impl fidl::endpoints::SynchronousProxy for LifecycleSynchronousProxy {
81    type Proxy = LifecycleProxy;
82    type Protocol = LifecycleMarker;
83
84    fn from_channel(inner: fidl::Channel) -> Self {
85        Self::new(inner)
86    }
87
88    fn into_channel(self) -> fidl::Channel {
89        self.client.into_channel()
90    }
91
92    fn as_channel(&self) -> &fidl::Channel {
93        self.client.as_channel()
94    }
95}
96
97#[cfg(target_os = "fuchsia")]
98impl LifecycleSynchronousProxy {
99    pub fn new(channel: fidl::Channel) -> Self {
100        Self { client: fidl::client::sync::Client::new(channel) }
101    }
102
103    pub fn into_channel(self) -> fidl::Channel {
104        self.client.into_channel()
105    }
106
107    /// Waits until an event arrives and returns it. It is safe for other
108    /// threads to make concurrent requests while waiting for an event.
109    pub fn wait_for_event(
110        &self,
111        deadline: zx::MonotonicInstant,
112    ) -> Result<LifecycleEvent, fidl::Error> {
113        LifecycleEvent::decode(self.client.wait_for_event::<LifecycleMarker>(deadline)?)
114    }
115
116    /// The process must clean up its state in preparation for termination, and
117    /// must close the channel hosting the `Lifecycle` protocol when it is
118    /// ready to be terminated. The process should exit after it completes its
119    /// cleanup. At the discretion of the system the process may be terminated
120    /// before it closes the `Lifecycle` channel.
121    pub fn r#stop(&self) -> Result<(), fidl::Error> {
122        self.client.send::<fidl::encoding::EmptyPayload>(
123            (),
124            0x64b176f1744c6f15,
125            fidl::encoding::DynamicFlags::empty(),
126        )
127    }
128}
129
130#[cfg(target_os = "fuchsia")]
131impl From<LifecycleSynchronousProxy> for zx::NullableHandle {
132    fn from(value: LifecycleSynchronousProxy) -> Self {
133        value.into_channel().into()
134    }
135}
136
137#[cfg(target_os = "fuchsia")]
138impl From<fidl::Channel> for LifecycleSynchronousProxy {
139    fn from(value: fidl::Channel) -> Self {
140        Self::new(value)
141    }
142}
143
144#[cfg(target_os = "fuchsia")]
145impl fidl::endpoints::FromClient for LifecycleSynchronousProxy {
146    type Protocol = LifecycleMarker;
147
148    fn from_client(value: fidl::endpoints::ClientEnd<LifecycleMarker>) -> Self {
149        Self::new(value.into_channel())
150    }
151}
152
153#[derive(Debug, Clone)]
154pub struct LifecycleProxy {
155    client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
156}
157
158impl fidl::endpoints::Proxy for LifecycleProxy {
159    type Protocol = LifecycleMarker;
160
161    fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
162        Self::new(inner)
163    }
164
165    fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
166        self.client.into_channel().map_err(|client| Self { client })
167    }
168
169    fn as_channel(&self) -> &::fidl::AsyncChannel {
170        self.client.as_channel()
171    }
172}
173
174impl LifecycleProxy {
175    /// Create a new Proxy for fuchsia.process.lifecycle/Lifecycle.
176    pub fn new(channel: ::fidl::AsyncChannel) -> Self {
177        let protocol_name = <LifecycleMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
178        Self { client: fidl::client::Client::new(channel, protocol_name) }
179    }
180
181    /// Get a Stream of events from the remote end of the protocol.
182    ///
183    /// # Panics
184    ///
185    /// Panics if the event stream was already taken.
186    pub fn take_event_stream(&self) -> LifecycleEventStream {
187        LifecycleEventStream { event_receiver: self.client.take_event_receiver() }
188    }
189
190    /// The process must clean up its state in preparation for termination, and
191    /// must close the channel hosting the `Lifecycle` protocol when it is
192    /// ready to be terminated. The process should exit after it completes its
193    /// cleanup. At the discretion of the system the process may be terminated
194    /// before it closes the `Lifecycle` channel.
195    pub fn r#stop(&self) -> Result<(), fidl::Error> {
196        LifecycleProxyInterface::r#stop(self)
197    }
198}
199
200impl LifecycleProxyInterface for LifecycleProxy {
201    fn r#stop(&self) -> Result<(), fidl::Error> {
202        self.client.send::<fidl::encoding::EmptyPayload>(
203            (),
204            0x64b176f1744c6f15,
205            fidl::encoding::DynamicFlags::empty(),
206        )
207    }
208}
209
210pub struct LifecycleEventStream {
211    event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
212}
213
214impl std::marker::Unpin for LifecycleEventStream {}
215
216impl futures::stream::FusedStream for LifecycleEventStream {
217    fn is_terminated(&self) -> bool {
218        self.event_receiver.is_terminated()
219    }
220}
221
222impl futures::Stream for LifecycleEventStream {
223    type Item = Result<LifecycleEvent, fidl::Error>;
224
225    fn poll_next(
226        mut self: std::pin::Pin<&mut Self>,
227        cx: &mut std::task::Context<'_>,
228    ) -> std::task::Poll<Option<Self::Item>> {
229        match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
230            &mut self.event_receiver,
231            cx
232        )?) {
233            Some(buf) => std::task::Poll::Ready(Some(LifecycleEvent::decode(buf))),
234            None => std::task::Poll::Ready(None),
235        }
236    }
237}
238
239#[derive(Debug)]
240pub enum LifecycleEvent {
241    OnEscrow { payload: LifecycleOnEscrowRequest },
242}
243
244impl LifecycleEvent {
245    #[allow(irrefutable_let_patterns)]
246    pub fn into_on_escrow(self) -> Option<LifecycleOnEscrowRequest> {
247        if let LifecycleEvent::OnEscrow { payload } = self { Some((payload)) } else { None }
248    }
249
250    /// Decodes a message buffer as a [`LifecycleEvent`].
251    fn decode(
252        mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
253    ) -> Result<LifecycleEvent, fidl::Error> {
254        let (bytes, _handles) = buf.split_mut();
255        let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
256        debug_assert_eq!(tx_header.tx_id, 0);
257        match tx_header.ordinal {
258            0x3de9c2fcb734ed48 => {
259                let mut out = fidl::new_empty!(
260                    LifecycleOnEscrowRequest,
261                    fidl::encoding::DefaultFuchsiaResourceDialect
262                );
263                fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<LifecycleOnEscrowRequest>(&tx_header, _body_bytes, _handles, &mut out)?;
264                Ok((LifecycleEvent::OnEscrow { payload: out }))
265            }
266            _ => Err(fidl::Error::UnknownOrdinal {
267                ordinal: tx_header.ordinal,
268                protocol_name: <LifecycleMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
269            }),
270        }
271    }
272}
273
274/// A Stream of incoming requests for fuchsia.process.lifecycle/Lifecycle.
275pub struct LifecycleRequestStream {
276    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
277    is_terminated: bool,
278}
279
280impl std::marker::Unpin for LifecycleRequestStream {}
281
282impl futures::stream::FusedStream for LifecycleRequestStream {
283    fn is_terminated(&self) -> bool {
284        self.is_terminated
285    }
286}
287
288impl fidl::endpoints::RequestStream for LifecycleRequestStream {
289    type Protocol = LifecycleMarker;
290    type ControlHandle = LifecycleControlHandle;
291
292    fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
293        Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
294    }
295
296    fn control_handle(&self) -> Self::ControlHandle {
297        LifecycleControlHandle { inner: self.inner.clone() }
298    }
299
300    fn into_inner(
301        self,
302    ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
303    {
304        (self.inner, self.is_terminated)
305    }
306
307    fn from_inner(
308        inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
309        is_terminated: bool,
310    ) -> Self {
311        Self { inner, is_terminated }
312    }
313}
314
315impl futures::Stream for LifecycleRequestStream {
316    type Item = Result<LifecycleRequest, fidl::Error>;
317
318    fn poll_next(
319        mut self: std::pin::Pin<&mut Self>,
320        cx: &mut std::task::Context<'_>,
321    ) -> std::task::Poll<Option<Self::Item>> {
322        let this = &mut *self;
323        if this.inner.check_shutdown(cx) {
324            this.is_terminated = true;
325            return std::task::Poll::Ready(None);
326        }
327        if this.is_terminated {
328            panic!("polled LifecycleRequestStream after completion");
329        }
330        fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
331            |bytes, handles| {
332                match this.inner.channel().read_etc(cx, bytes, handles) {
333                    std::task::Poll::Ready(Ok(())) => {}
334                    std::task::Poll::Pending => return std::task::Poll::Pending,
335                    std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
336                        this.is_terminated = true;
337                        return std::task::Poll::Ready(None);
338                    }
339                    std::task::Poll::Ready(Err(e)) => {
340                        return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
341                            e.into(),
342                        ))));
343                    }
344                }
345
346                // A message has been received from the channel
347                let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
348
349                std::task::Poll::Ready(Some(match header.ordinal {
350                    0x64b176f1744c6f15 => {
351                        header.validate_request_tx_id(fidl::MethodType::OneWay)?;
352                        let mut req = fidl::new_empty!(
353                            fidl::encoding::EmptyPayload,
354                            fidl::encoding::DefaultFuchsiaResourceDialect
355                        );
356                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
357                        let control_handle = LifecycleControlHandle { inner: this.inner.clone() };
358                        Ok(LifecycleRequest::Stop { control_handle })
359                    }
360                    _ => Err(fidl::Error::UnknownOrdinal {
361                        ordinal: header.ordinal,
362                        protocol_name:
363                            <LifecycleMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
364                    }),
365                }))
366            },
367        )
368    }
369}
370
371/// A component can implement the Lifecycle protocol to be notified of lifecycle
372/// events. It can also store some state in the framework, to be redelivered to
373/// the component the next time it is started (a practice called "escrowing").
374///
375/// The ELF Runner uses this protocol to communicate lifecycle changes
376/// to the component, for more details on how it uses this protocol see:
377/// https://fuchsia.dev/fuchsia-src/concepts/components/v2/elf_runner#lifecycle
378#[derive(Debug)]
379pub enum LifecycleRequest {
380    /// The process must clean up its state in preparation for termination, and
381    /// must close the channel hosting the `Lifecycle` protocol when it is
382    /// ready to be terminated. The process should exit after it completes its
383    /// cleanup. At the discretion of the system the process may be terminated
384    /// before it closes the `Lifecycle` channel.
385    Stop { control_handle: LifecycleControlHandle },
386}
387
388impl LifecycleRequest {
389    #[allow(irrefutable_let_patterns)]
390    pub fn into_stop(self) -> Option<(LifecycleControlHandle)> {
391        if let LifecycleRequest::Stop { control_handle } = self {
392            Some((control_handle))
393        } else {
394            None
395        }
396    }
397
398    /// Name of the method defined in FIDL
399    pub fn method_name(&self) -> &'static str {
400        match *self {
401            LifecycleRequest::Stop { .. } => "stop",
402        }
403    }
404}
405
406#[derive(Debug, Clone)]
407pub struct LifecycleControlHandle {
408    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
409}
410
411impl LifecycleControlHandle {
412    pub fn shutdown_with_epitaph(&self, status: impl Into<fidl::Epitaph>) {
413        self.inner.shutdown_with_epitaph(status.into())
414    }
415}
416
417impl fidl::endpoints::ControlHandle for LifecycleControlHandle {
418    fn shutdown(&self) {
419        self.inner.shutdown()
420    }
421
422    fn shutdown_with_epitaph(&self, status: fidl::Epitaph) {
423        self.inner.shutdown_with_epitaph(status)
424    }
425
426    fn is_closed(&self) -> bool {
427        self.inner.channel().is_closed()
428    }
429    fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
430        self.inner.channel().on_closed()
431    }
432
433    #[cfg(target_os = "fuchsia")]
434    fn signal_peer(
435        &self,
436        clear_mask: zx::Signals,
437        set_mask: zx::Signals,
438    ) -> Result<(), zx_status::Status> {
439        use fidl::Peered;
440        self.inner.channel().signal_peer(clear_mask, set_mask)
441    }
442}
443
444impl LifecycleControlHandle {
445    pub fn send_on_escrow(&self, mut payload: LifecycleOnEscrowRequest) -> Result<(), fidl::Error> {
446        self.inner.send::<LifecycleOnEscrowRequest>(
447            &mut payload,
448            0,
449            0x3de9c2fcb734ed48,
450            fidl::encoding::DynamicFlags::empty(),
451        )
452    }
453}
454
455mod internal {
456    use super::*;
457
458    impl LifecycleOnEscrowRequest {
459        #[inline(always)]
460        fn max_ordinal_present(&self) -> u64 {
461            if let Some(_) = self.recoverable_bytes {
462                return 4;
463            }
464            if let Some(_) = self.escrowed_dictionary_handle {
465                return 3;
466            }
467            if let Some(_) = self.escrowed_dictionary {
468                return 2;
469            }
470            if let Some(_) = self.outgoing_dir {
471                return 1;
472            }
473            0
474        }
475    }
476
477    impl fidl::encoding::ResourceTypeMarker for LifecycleOnEscrowRequest {
478        type Borrowed<'a> = &'a mut Self;
479        fn take_or_borrow<'a>(
480            value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
481        ) -> Self::Borrowed<'a> {
482            value
483        }
484    }
485
486    unsafe impl fidl::encoding::TypeMarker for LifecycleOnEscrowRequest {
487        type Owned = Self;
488
489        #[inline(always)]
490        fn inline_align(_context: fidl::encoding::Context) -> usize {
491            8
492        }
493
494        #[inline(always)]
495        fn inline_size(_context: fidl::encoding::Context) -> usize {
496            16
497        }
498    }
499
500    unsafe impl
501        fidl::encoding::Encode<
502            LifecycleOnEscrowRequest,
503            fidl::encoding::DefaultFuchsiaResourceDialect,
504        > for &mut LifecycleOnEscrowRequest
505    {
506        unsafe fn encode(
507            self,
508            encoder: &mut fidl::encoding::Encoder<
509                '_,
510                fidl::encoding::DefaultFuchsiaResourceDialect,
511            >,
512            offset: usize,
513            mut depth: fidl::encoding::Depth,
514        ) -> fidl::Result<()> {
515            encoder.debug_check_bounds::<LifecycleOnEscrowRequest>(offset);
516            // Vector header
517            let max_ordinal: u64 = self.max_ordinal_present();
518            encoder.write_num(max_ordinal, offset);
519            encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
520            // Calling encoder.out_of_line_offset(0) is not allowed.
521            if max_ordinal == 0 {
522                return Ok(());
523            }
524            depth.increment()?;
525            let envelope_size = 8;
526            let bytes_len = max_ordinal as usize * envelope_size;
527            #[allow(unused_variables)]
528            let offset = encoder.out_of_line_offset(bytes_len);
529            let mut _prev_end_offset: usize = 0;
530            if 1 > max_ordinal {
531                return Ok(());
532            }
533
534            // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
535            // are envelope_size bytes.
536            let cur_offset: usize = (1 - 1) * envelope_size;
537
538            // Zero reserved fields.
539            encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
540
541            // Safety:
542            // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
543            // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
544            //   envelope_size bytes, there is always sufficient room.
545            fidl::encoding::encode_in_envelope_optional::<
546                fidl::encoding::Endpoint<
547                    fidl::endpoints::ServerEnd<fidl_fuchsia_io::DirectoryMarker>,
548                >,
549                fidl::encoding::DefaultFuchsiaResourceDialect,
550            >(
551                self.outgoing_dir.as_mut().map(
552                    <fidl::encoding::Endpoint<
553                        fidl::endpoints::ServerEnd<fidl_fuchsia_io::DirectoryMarker>,
554                    > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
555                ),
556                encoder,
557                offset + cur_offset,
558                depth,
559            )?;
560
561            _prev_end_offset = cur_offset + envelope_size;
562            if 2 > max_ordinal {
563                return Ok(());
564            }
565
566            // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
567            // are envelope_size bytes.
568            let cur_offset: usize = (2 - 1) * envelope_size;
569
570            // Zero reserved fields.
571            encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
572
573            // Safety:
574            // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
575            // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
576            //   envelope_size bytes, there is always sufficient room.
577            fidl::encoding::encode_in_envelope_optional::<fidl_fuchsia_component_sandbox::DictionaryRef, fidl::encoding::DefaultFuchsiaResourceDialect>(
578            self.escrowed_dictionary.as_mut().map(<fidl_fuchsia_component_sandbox::DictionaryRef as fidl::encoding::ResourceTypeMarker>::take_or_borrow),
579            encoder, offset + cur_offset, depth
580        )?;
581
582            _prev_end_offset = cur_offset + envelope_size;
583            if 3 > max_ordinal {
584                return Ok(());
585            }
586
587            // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
588            // are envelope_size bytes.
589            let cur_offset: usize = (3 - 1) * envelope_size;
590
591            // Zero reserved fields.
592            encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
593
594            // Safety:
595            // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
596            // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
597            //   envelope_size bytes, there is always sufficient room.
598            fidl::encoding::encode_in_envelope_optional::<
599                fidl::encoding::HandleType<
600                    fidl::EventPair,
601                    { fidl::ObjectType::EVENTPAIR.into_raw() },
602                    2147483648,
603                >,
604                fidl::encoding::DefaultFuchsiaResourceDialect,
605            >(
606                self.escrowed_dictionary_handle.as_mut().map(
607                    <fidl::encoding::HandleType<
608                        fidl::EventPair,
609                        { fidl::ObjectType::EVENTPAIR.into_raw() },
610                        2147483648,
611                    > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
612                ),
613                encoder,
614                offset + cur_offset,
615                depth,
616            )?;
617
618            _prev_end_offset = cur_offset + envelope_size;
619            if 4 > max_ordinal {
620                return Ok(());
621            }
622
623            // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
624            // are envelope_size bytes.
625            let cur_offset: usize = (4 - 1) * envelope_size;
626
627            // Zero reserved fields.
628            encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
629
630            // Safety:
631            // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
632            // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
633            //   envelope_size bytes, there is always sufficient room.
634            fidl::encoding::encode_in_envelope_optional::<
635                u64,
636                fidl::encoding::DefaultFuchsiaResourceDialect,
637            >(
638                self.recoverable_bytes
639                    .as_ref()
640                    .map(<u64 as fidl::encoding::ValueTypeMarker>::borrow),
641                encoder,
642                offset + cur_offset,
643                depth,
644            )?;
645
646            _prev_end_offset = cur_offset + envelope_size;
647
648            Ok(())
649        }
650    }
651
652    impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
653        for LifecycleOnEscrowRequest
654    {
655        #[inline(always)]
656        fn new_empty() -> Self {
657            Self::default()
658        }
659
660        unsafe fn decode(
661            &mut self,
662            decoder: &mut fidl::encoding::Decoder<
663                '_,
664                fidl::encoding::DefaultFuchsiaResourceDialect,
665            >,
666            offset: usize,
667            mut depth: fidl::encoding::Depth,
668        ) -> fidl::Result<()> {
669            decoder.debug_check_bounds::<Self>(offset);
670            let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
671                None => return Err(fidl::Error::NotNullable),
672                Some(len) => len,
673            };
674            // Calling decoder.out_of_line_offset(0) is not allowed.
675            if len == 0 {
676                return Ok(());
677            };
678            depth.increment()?;
679            let envelope_size = 8;
680            let bytes_len = len * envelope_size;
681            let offset = decoder.out_of_line_offset(bytes_len)?;
682            // Decode the envelope for each type.
683            let mut _next_ordinal_to_read = 0;
684            let mut next_offset = offset;
685            let end_offset = offset + bytes_len;
686            _next_ordinal_to_read += 1;
687            if next_offset >= end_offset {
688                return Ok(());
689            }
690
691            // Decode unknown envelopes for gaps in ordinals.
692            while _next_ordinal_to_read < 1 {
693                fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
694                _next_ordinal_to_read += 1;
695                next_offset += envelope_size;
696            }
697
698            let next_out_of_line = decoder.next_out_of_line();
699            let handles_before = decoder.remaining_handles();
700            if let Some((inlined, num_bytes, num_handles)) =
701                fidl::encoding::decode_envelope_header(decoder, next_offset)?
702            {
703                let member_inline_size = <fidl::encoding::Endpoint<
704                    fidl::endpoints::ServerEnd<fidl_fuchsia_io::DirectoryMarker>,
705                > as fidl::encoding::TypeMarker>::inline_size(
706                    decoder.context
707                );
708                if inlined != (member_inline_size <= 4) {
709                    return Err(fidl::Error::InvalidInlineBitInEnvelope);
710                }
711                let inner_offset;
712                let mut inner_depth = depth.clone();
713                if inlined {
714                    decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
715                    inner_offset = next_offset;
716                } else {
717                    inner_offset = decoder.out_of_line_offset(member_inline_size)?;
718                    inner_depth.increment()?;
719                }
720                let val_ref = self.outgoing_dir.get_or_insert_with(|| {
721                    fidl::new_empty!(
722                        fidl::encoding::Endpoint<
723                            fidl::endpoints::ServerEnd<fidl_fuchsia_io::DirectoryMarker>,
724                        >,
725                        fidl::encoding::DefaultFuchsiaResourceDialect
726                    )
727                });
728                fidl::decode!(
729                    fidl::encoding::Endpoint<
730                        fidl::endpoints::ServerEnd<fidl_fuchsia_io::DirectoryMarker>,
731                    >,
732                    fidl::encoding::DefaultFuchsiaResourceDialect,
733                    val_ref,
734                    decoder,
735                    inner_offset,
736                    inner_depth
737                )?;
738                if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
739                {
740                    return Err(fidl::Error::InvalidNumBytesInEnvelope);
741                }
742                if handles_before != decoder.remaining_handles() + (num_handles as usize) {
743                    return Err(fidl::Error::InvalidNumHandlesInEnvelope);
744                }
745            }
746
747            next_offset += envelope_size;
748            _next_ordinal_to_read += 1;
749            if next_offset >= end_offset {
750                return Ok(());
751            }
752
753            // Decode unknown envelopes for gaps in ordinals.
754            while _next_ordinal_to_read < 2 {
755                fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
756                _next_ordinal_to_read += 1;
757                next_offset += envelope_size;
758            }
759
760            let next_out_of_line = decoder.next_out_of_line();
761            let handles_before = decoder.remaining_handles();
762            if let Some((inlined, num_bytes, num_handles)) =
763                fidl::encoding::decode_envelope_header(decoder, next_offset)?
764            {
765                let member_inline_size = <fidl_fuchsia_component_sandbox::DictionaryRef as fidl::encoding::TypeMarker>::inline_size(decoder.context);
766                if inlined != (member_inline_size <= 4) {
767                    return Err(fidl::Error::InvalidInlineBitInEnvelope);
768                }
769                let inner_offset;
770                let mut inner_depth = depth.clone();
771                if inlined {
772                    decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
773                    inner_offset = next_offset;
774                } else {
775                    inner_offset = decoder.out_of_line_offset(member_inline_size)?;
776                    inner_depth.increment()?;
777                }
778                let val_ref = self.escrowed_dictionary.get_or_insert_with(|| {
779                    fidl::new_empty!(
780                        fidl_fuchsia_component_sandbox::DictionaryRef,
781                        fidl::encoding::DefaultFuchsiaResourceDialect
782                    )
783                });
784                fidl::decode!(
785                    fidl_fuchsia_component_sandbox::DictionaryRef,
786                    fidl::encoding::DefaultFuchsiaResourceDialect,
787                    val_ref,
788                    decoder,
789                    inner_offset,
790                    inner_depth
791                )?;
792                if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
793                {
794                    return Err(fidl::Error::InvalidNumBytesInEnvelope);
795                }
796                if handles_before != decoder.remaining_handles() + (num_handles as usize) {
797                    return Err(fidl::Error::InvalidNumHandlesInEnvelope);
798                }
799            }
800
801            next_offset += envelope_size;
802            _next_ordinal_to_read += 1;
803            if next_offset >= end_offset {
804                return Ok(());
805            }
806
807            // Decode unknown envelopes for gaps in ordinals.
808            while _next_ordinal_to_read < 3 {
809                fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
810                _next_ordinal_to_read += 1;
811                next_offset += envelope_size;
812            }
813
814            let next_out_of_line = decoder.next_out_of_line();
815            let handles_before = decoder.remaining_handles();
816            if let Some((inlined, num_bytes, num_handles)) =
817                fidl::encoding::decode_envelope_header(decoder, next_offset)?
818            {
819                let member_inline_size = <fidl::encoding::HandleType<
820                    fidl::EventPair,
821                    { fidl::ObjectType::EVENTPAIR.into_raw() },
822                    2147483648,
823                > as fidl::encoding::TypeMarker>::inline_size(
824                    decoder.context
825                );
826                if inlined != (member_inline_size <= 4) {
827                    return Err(fidl::Error::InvalidInlineBitInEnvelope);
828                }
829                let inner_offset;
830                let mut inner_depth = depth.clone();
831                if inlined {
832                    decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
833                    inner_offset = next_offset;
834                } else {
835                    inner_offset = decoder.out_of_line_offset(member_inline_size)?;
836                    inner_depth.increment()?;
837                }
838                let val_ref =
839                self.escrowed_dictionary_handle.get_or_insert_with(|| fidl::new_empty!(fidl::encoding::HandleType<fidl::EventPair, { fidl::ObjectType::EVENTPAIR.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect));
840                fidl::decode!(fidl::encoding::HandleType<fidl::EventPair, { fidl::ObjectType::EVENTPAIR.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, val_ref, decoder, inner_offset, inner_depth)?;
841                if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
842                {
843                    return Err(fidl::Error::InvalidNumBytesInEnvelope);
844                }
845                if handles_before != decoder.remaining_handles() + (num_handles as usize) {
846                    return Err(fidl::Error::InvalidNumHandlesInEnvelope);
847                }
848            }
849
850            next_offset += envelope_size;
851            _next_ordinal_to_read += 1;
852            if next_offset >= end_offset {
853                return Ok(());
854            }
855
856            // Decode unknown envelopes for gaps in ordinals.
857            while _next_ordinal_to_read < 4 {
858                fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
859                _next_ordinal_to_read += 1;
860                next_offset += envelope_size;
861            }
862
863            let next_out_of_line = decoder.next_out_of_line();
864            let handles_before = decoder.remaining_handles();
865            if let Some((inlined, num_bytes, num_handles)) =
866                fidl::encoding::decode_envelope_header(decoder, next_offset)?
867            {
868                let member_inline_size =
869                    <u64 as fidl::encoding::TypeMarker>::inline_size(decoder.context);
870                if inlined != (member_inline_size <= 4) {
871                    return Err(fidl::Error::InvalidInlineBitInEnvelope);
872                }
873                let inner_offset;
874                let mut inner_depth = depth.clone();
875                if inlined {
876                    decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
877                    inner_offset = next_offset;
878                } else {
879                    inner_offset = decoder.out_of_line_offset(member_inline_size)?;
880                    inner_depth.increment()?;
881                }
882                let val_ref = self.recoverable_bytes.get_or_insert_with(|| {
883                    fidl::new_empty!(u64, fidl::encoding::DefaultFuchsiaResourceDialect)
884                });
885                fidl::decode!(
886                    u64,
887                    fidl::encoding::DefaultFuchsiaResourceDialect,
888                    val_ref,
889                    decoder,
890                    inner_offset,
891                    inner_depth
892                )?;
893                if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
894                {
895                    return Err(fidl::Error::InvalidNumBytesInEnvelope);
896                }
897                if handles_before != decoder.remaining_handles() + (num_handles as usize) {
898                    return Err(fidl::Error::InvalidNumHandlesInEnvelope);
899                }
900            }
901
902            next_offset += envelope_size;
903
904            // Decode the remaining unknown envelopes.
905            while next_offset < end_offset {
906                _next_ordinal_to_read += 1;
907                fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
908                next_offset += envelope_size;
909            }
910
911            Ok(())
912        }
913    }
914}