fidl_fuchsia_hardware_block_driver/
fidl_fuchsia_hardware_block_driver.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 _};
10use futures::future::{self, MaybeDone, TryFutureExt};
11use zx_status;
12
13pub type Vmoid = u16;
14
15pub const BLOCK_GUID_LEN: u32 = 16;
16
17pub const BLOCK_VMOID_INVALID: u16 = 0;
18
19/// Multiple block I/O operations may be sent at once before a response is
20/// actually sent back. Block I/O ops may be sent concurrently to different
21/// vmoids, and they also may be sent to different groups at any point in time.
22///
23/// `MAX_TXN_GROUP_COUNT` "groups" are pre-allocated lanes separated on the
24/// block server.  Using a group allows multiple message to be buffered at once
25/// on a single communication channel before receiving a response.
26///
27/// Usage of groups is identified by the `GROUP_ITEM` flag, and is optional.
28///
29/// These groups may be referred to with a "groupid", in the range [0,
30/// `MAX_TXN_GROUP_COUNT`).
31///
32/// The protocol to communicate with a single group is as follows:
33/// 1) SEND [N - 1] messages with an allocated groupid for any value of 1 <= N.
34///    The `GROUP_ITEM` flag is set for these messages.
35/// 2) SEND a final Nth message with the same groupid. The `GROUP_ITEM
36///    | GROUP_LAST` flags are set for this message.
37/// 3) RECEIVE a single response from the Block I/O server after all N requests
38///    have completed. This response is sent once all operations either complete
39///    or a single operation fails. At this point, step (1) may begin again for
40///    the same groupid.
41///
42/// For `READ` and `WRITE`, N may be greater than 1. Otherwise,
43/// N == 1 (skipping step (1) in the protocol above).
44///
45/// Notes:
46/// - groupids may operate on any number of vmoids at once.
47/// - If additional requests are sent on the same groupid before step (3) has
48///   completed, then the additional request will not be processed. If
49///   `GROUP_LAST` is set, an error will be returned. Otherwise, the
50///   request will be silently dropped.
51/// - Messages within a group are not guaranteed to be processed in any order
52///   relative to each other.
53/// - All requests receive responses, except for ones with `GROUP_ITEM`
54///   that do not have `GROUP_LAST` set.
55///
56/// For example, the following is a valid sequence of transactions:
57///
58///   -> (groupid = 1, vmoid = 1, OP = Write | GroupItem,             reqid = 1)
59///   -> (groupid = 1, vmoid = 2, OP = Write | GroupItem,             reqid = 2)
60///   -> (groupid = 2, vmoid = 3, OP = Write | GroupItem | GroupLast, reqid = 0)
61///   <- Response sent to groupid = 2, reqid = 0
62///   -> (groupid = 1, vmoid = 1, OP = Read | GroupItem | GroupLast,  reqid = 3)
63///   <- Response sent to groupid = 1, reqid = 3
64///   -> (groupid = 3, vmoid = 1, OP = Write | GroupItem,             reqid = 4)
65///   -> (groupid = don't care, vmoid = 1, OP = Read, reqid = 5)
66///   <- Response sent to reqid = 5
67///   -> (groupid = 3, vmoid = 1, OP = Read | GroupItem | GroupLast,  reqid = 6)
68///   <- Response sent to groupid = 3, reqid = 6
69///
70/// Each transaction reads or writes up to `length` blocks from the device,
71/// starting at `dev_offset` blocks, into the VMO associated with `vmoid`,
72/// starting at `vmo_offset` blocks.  If the transaction is out of range, for
73/// example if `length` is too large or if `dev_offset` is beyond the end of the
74/// device, `ZX_ERR_OUT_OF_RANGE` is returned.
75pub const MAX_TXN_GROUP_COUNT: u32 = 8;
76
77bitflags! {
78    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
79    pub struct BlockIoFlag: u32 {
80        /// Associate the following request with `group`.
81        const GROUP_ITEM = 1;
82        /// Only respond after this request (and all previous within group) have
83        /// completed. Only valid with `GROUP_ITEM`.
84        const GROUP_LAST = 2;
85        /// Mark this operation as "Force Unit Access" (FUA), indicating that
86        /// it should not complete until the data is written to the non-volatile
87        /// medium (write), and that reads should bypass any on-device caches.
88        const FORCE_ACCESS = 4;
89    }
90}
91
92impl BlockIoFlag {
93    #[deprecated = "Strict bits should not use `has_unknown_bits`"]
94    #[inline(always)]
95    pub fn has_unknown_bits(&self) -> bool {
96        false
97    }
98
99    #[deprecated = "Strict bits should not use `get_unknown_bits`"]
100    #[inline(always)]
101    pub fn get_unknown_bits(&self) -> u32 {
102        0
103    }
104}
105
106#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
107#[repr(u8)]
108pub enum BlockOpcode {
109    /// Performs a regular data read or write from the device. The operation may
110    /// be cached internally.
111    Read = 1,
112    Write = 2,
113    /// Write any controller or device cached data to nonvolatile storage.
114    Flush = 3,
115    /// Instructs the device to invalidate a number of blocks, making them  usable
116    /// for storing something else. This is basically a "delete" optimization,
117    /// where the device is in charge of discarding the old content without
118    /// clients having to write a given pattern. The operation may be cached
119    /// internally.
120    Trim = 4,
121    /// Detaches the VMO from the block device.
122    CloseVmo = 5,
123}
124
125impl BlockOpcode {
126    #[inline]
127    pub fn from_primitive(prim: u8) -> Option<Self> {
128        match prim {
129            1 => Some(Self::Read),
130            2 => Some(Self::Write),
131            3 => Some(Self::Flush),
132            4 => Some(Self::Trim),
133            5 => Some(Self::CloseVmo),
134            _ => None,
135        }
136    }
137
138    #[inline]
139    pub const fn into_primitive(self) -> u8 {
140        self as u8
141    }
142
143    #[deprecated = "Strict enums should not use `is_unknown`"]
144    #[inline]
145    pub fn is_unknown(&self) -> bool {
146        false
147    }
148}
149
150#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
151pub struct BlockCommand {
152    pub opcode: BlockOpcode,
153    pub flags: BlockIoFlag,
154}
155
156impl fidl::Persistable for BlockCommand {}
157
158/// `READ`, `WRITE`
159#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
160pub struct BlockReadWrite {
161    /// Opcode and flags.
162    pub command: BlockCommand,
163    /// Available for temporary use.
164    pub extra: u32,
165    /// VMO of data to read or write.
166    pub vmo: fidl::Vmo,
167    /// Transfer length in blocks (0 is invalid).
168    pub length: u32,
169    /// Device offset in blocks.
170    pub offset_dev: u64,
171    /// VMO offset in blocks.
172    pub offset_vmo: u64,
173}
174
175impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect> for BlockReadWrite {}
176
177/// `TRIM`
178#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
179pub struct BlockTrim {
180    /// Opcode and flags.
181    pub command: BlockCommand,
182    /// Transfer length in blocks (0 is invalid).
183    pub length: u32,
184    /// Device offset in blocks.
185    pub offset_dev: u64,
186}
187
188impl fidl::Persistable for BlockTrim {}
189
190#[derive(Clone, Debug, PartialEq)]
191pub struct CommonQueryResponse {
192    pub info: fidl_fuchsia_hardware_block::BlockInfo,
193    pub block_op_size: u64,
194}
195
196impl fidl::Persistable for CommonQueryResponse {}
197
198#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
199pub struct CommonQueueRequest {
200    pub txn: BlockOp,
201}
202
203impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect> for CommonQueueRequest {}
204
205#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
206pub struct CommonQueueResponse {
207    pub status: i32,
208    pub op: BlockOp,
209}
210
211impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect> for CommonQueueResponse {}
212
213#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
214pub enum BlockOp {
215    /// All Commands
216    Command(BlockCommand),
217    /// Read and Write ops use rw for parameters.
218    Rw(BlockReadWrite),
219    Trim(BlockTrim),
220}
221
222impl BlockOp {
223    #[inline]
224    pub fn ordinal(&self) -> u64 {
225        match *self {
226            Self::Command(_) => 1,
227            Self::Rw(_) => 2,
228            Self::Trim(_) => 3,
229        }
230    }
231
232    #[deprecated = "Strict unions should not use `is_unknown`"]
233    #[inline]
234    pub fn is_unknown(&self) -> bool {
235        false
236    }
237}
238
239impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect> for BlockOp {}
240
241#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
242pub struct CommonMarker;
243
244impl fidl::endpoints::ProtocolMarker for CommonMarker {
245    type Proxy = CommonProxy;
246    type RequestStream = CommonRequestStream;
247    #[cfg(target_os = "fuchsia")]
248    type SynchronousProxy = CommonSynchronousProxy;
249
250    const DEBUG_NAME: &'static str = "(anonymous) Common";
251}
252
253pub trait CommonProxyInterface: Send + Sync {
254    type QueryResponseFut: std::future::Future<
255            Output = Result<(fidl_fuchsia_hardware_block::BlockInfo, u64), fidl::Error>,
256        > + Send;
257    fn r#query(&self) -> Self::QueryResponseFut;
258    type QueueResponseFut: std::future::Future<Output = Result<(i32, BlockOp), fidl::Error>> + Send;
259    fn r#queue(&self, txn: BlockOp) -> Self::QueueResponseFut;
260}
261#[derive(Debug)]
262#[cfg(target_os = "fuchsia")]
263pub struct CommonSynchronousProxy {
264    client: fidl::client::sync::Client,
265}
266
267#[cfg(target_os = "fuchsia")]
268impl fidl::endpoints::SynchronousProxy for CommonSynchronousProxy {
269    type Proxy = CommonProxy;
270    type Protocol = CommonMarker;
271
272    fn from_channel(inner: fidl::Channel) -> Self {
273        Self::new(inner)
274    }
275
276    fn into_channel(self) -> fidl::Channel {
277        self.client.into_channel()
278    }
279
280    fn as_channel(&self) -> &fidl::Channel {
281        self.client.as_channel()
282    }
283}
284
285#[cfg(target_os = "fuchsia")]
286impl CommonSynchronousProxy {
287    pub fn new(channel: fidl::Channel) -> Self {
288        let protocol_name = <CommonMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
289        Self { client: fidl::client::sync::Client::new(channel, protocol_name) }
290    }
291
292    pub fn into_channel(self) -> fidl::Channel {
293        self.client.into_channel()
294    }
295
296    /// Waits until an event arrives and returns it. It is safe for other
297    /// threads to make concurrent requests while waiting for an event.
298    pub fn wait_for_event(
299        &self,
300        deadline: zx::MonotonicInstant,
301    ) -> Result<CommonEvent, fidl::Error> {
302        CommonEvent::decode(self.client.wait_for_event(deadline)?)
303    }
304
305    /// Obtains the parameters of the block device (`block_info_t`) and the
306    /// required size of `block_txn_t`. The `block_txn_t`s submitted via
307    /// `Queue()` must have `block_op_size_out - sizeof(block_op_t)` bytes
308    /// available at the end of the structure for the use of the driver.
309    pub fn r#query(
310        &self,
311        ___deadline: zx::MonotonicInstant,
312    ) -> Result<(fidl_fuchsia_hardware_block::BlockInfo, u64), fidl::Error> {
313        let _response =
314            self.client.send_query::<fidl::encoding::EmptyPayload, CommonQueryResponse>(
315                (),
316                0x1551192b715c20b0,
317                fidl::encoding::DynamicFlags::empty(),
318                ___deadline,
319            )?;
320        Ok((_response.info, _response.block_op_size))
321    }
322
323    /// Submits an I/O request for processing. Ownership of `op` is transferred
324    /// to callee until `completion_cb` is invoked. Success or failure will be
325    /// reported via the `completion_cb`. This callback may be called before the
326    /// `Queue()` method returns.
327    pub fn r#queue(
328        &self,
329        mut txn: BlockOp,
330        ___deadline: zx::MonotonicInstant,
331    ) -> Result<(i32, BlockOp), fidl::Error> {
332        let _response = self.client.send_query::<CommonQueueRequest, CommonQueueResponse>(
333            (&mut txn,),
334            0x4d57f58df2b01c6a,
335            fidl::encoding::DynamicFlags::empty(),
336            ___deadline,
337        )?;
338        Ok((_response.status, _response.op))
339    }
340}
341
342#[derive(Debug, Clone)]
343pub struct CommonProxy {
344    client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
345}
346
347impl fidl::endpoints::Proxy for CommonProxy {
348    type Protocol = CommonMarker;
349
350    fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
351        Self::new(inner)
352    }
353
354    fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
355        self.client.into_channel().map_err(|client| Self { client })
356    }
357
358    fn as_channel(&self) -> &::fidl::AsyncChannel {
359        self.client.as_channel()
360    }
361}
362
363impl CommonProxy {
364    /// Create a new Proxy for fuchsia.hardware.block.driver/Common.
365    pub fn new(channel: ::fidl::AsyncChannel) -> Self {
366        let protocol_name = <CommonMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
367        Self { client: fidl::client::Client::new(channel, protocol_name) }
368    }
369
370    /// Get a Stream of events from the remote end of the protocol.
371    ///
372    /// # Panics
373    ///
374    /// Panics if the event stream was already taken.
375    pub fn take_event_stream(&self) -> CommonEventStream {
376        CommonEventStream { event_receiver: self.client.take_event_receiver() }
377    }
378
379    /// Obtains the parameters of the block device (`block_info_t`) and the
380    /// required size of `block_txn_t`. The `block_txn_t`s submitted via
381    /// `Queue()` must have `block_op_size_out - sizeof(block_op_t)` bytes
382    /// available at the end of the structure for the use of the driver.
383    pub fn r#query(
384        &self,
385    ) -> fidl::client::QueryResponseFut<
386        (fidl_fuchsia_hardware_block::BlockInfo, u64),
387        fidl::encoding::DefaultFuchsiaResourceDialect,
388    > {
389        CommonProxyInterface::r#query(self)
390    }
391
392    /// Submits an I/O request for processing. Ownership of `op` is transferred
393    /// to callee until `completion_cb` is invoked. Success or failure will be
394    /// reported via the `completion_cb`. This callback may be called before the
395    /// `Queue()` method returns.
396    pub fn r#queue(
397        &self,
398        mut txn: BlockOp,
399    ) -> fidl::client::QueryResponseFut<(i32, BlockOp), fidl::encoding::DefaultFuchsiaResourceDialect>
400    {
401        CommonProxyInterface::r#queue(self, txn)
402    }
403}
404
405impl CommonProxyInterface for CommonProxy {
406    type QueryResponseFut = fidl::client::QueryResponseFut<
407        (fidl_fuchsia_hardware_block::BlockInfo, u64),
408        fidl::encoding::DefaultFuchsiaResourceDialect,
409    >;
410    fn r#query(&self) -> Self::QueryResponseFut {
411        fn _decode(
412            mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
413        ) -> Result<(fidl_fuchsia_hardware_block::BlockInfo, u64), fidl::Error> {
414            let _response = fidl::client::decode_transaction_body::<
415                CommonQueryResponse,
416                fidl::encoding::DefaultFuchsiaResourceDialect,
417                0x1551192b715c20b0,
418            >(_buf?)?;
419            Ok((_response.info, _response.block_op_size))
420        }
421        self.client.send_query_and_decode::<
422            fidl::encoding::EmptyPayload,
423            (fidl_fuchsia_hardware_block::BlockInfo, u64),
424        >(
425            (),
426            0x1551192b715c20b0,
427            fidl::encoding::DynamicFlags::empty(),
428            _decode,
429        )
430    }
431
432    type QueueResponseFut = fidl::client::QueryResponseFut<
433        (i32, BlockOp),
434        fidl::encoding::DefaultFuchsiaResourceDialect,
435    >;
436    fn r#queue(&self, mut txn: BlockOp) -> Self::QueueResponseFut {
437        fn _decode(
438            mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
439        ) -> Result<(i32, BlockOp), fidl::Error> {
440            let _response = fidl::client::decode_transaction_body::<
441                CommonQueueResponse,
442                fidl::encoding::DefaultFuchsiaResourceDialect,
443                0x4d57f58df2b01c6a,
444            >(_buf?)?;
445            Ok((_response.status, _response.op))
446        }
447        self.client.send_query_and_decode::<CommonQueueRequest, (i32, BlockOp)>(
448            (&mut txn,),
449            0x4d57f58df2b01c6a,
450            fidl::encoding::DynamicFlags::empty(),
451            _decode,
452        )
453    }
454}
455
456pub struct CommonEventStream {
457    event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
458}
459
460impl std::marker::Unpin for CommonEventStream {}
461
462impl futures::stream::FusedStream for CommonEventStream {
463    fn is_terminated(&self) -> bool {
464        self.event_receiver.is_terminated()
465    }
466}
467
468impl futures::Stream for CommonEventStream {
469    type Item = Result<CommonEvent, fidl::Error>;
470
471    fn poll_next(
472        mut self: std::pin::Pin<&mut Self>,
473        cx: &mut std::task::Context<'_>,
474    ) -> std::task::Poll<Option<Self::Item>> {
475        match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
476            &mut self.event_receiver,
477            cx
478        )?) {
479            Some(buf) => std::task::Poll::Ready(Some(CommonEvent::decode(buf))),
480            None => std::task::Poll::Ready(None),
481        }
482    }
483}
484
485#[derive(Debug)]
486pub enum CommonEvent {}
487
488impl CommonEvent {
489    /// Decodes a message buffer as a [`CommonEvent`].
490    fn decode(
491        mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
492    ) -> Result<CommonEvent, fidl::Error> {
493        let (bytes, _handles) = buf.split_mut();
494        let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
495        debug_assert_eq!(tx_header.tx_id, 0);
496        match tx_header.ordinal {
497            _ => Err(fidl::Error::UnknownOrdinal {
498                ordinal: tx_header.ordinal,
499                protocol_name: <CommonMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
500            }),
501        }
502    }
503}
504
505/// A Stream of incoming requests for fuchsia.hardware.block.driver/Common.
506pub struct CommonRequestStream {
507    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
508    is_terminated: bool,
509}
510
511impl std::marker::Unpin for CommonRequestStream {}
512
513impl futures::stream::FusedStream for CommonRequestStream {
514    fn is_terminated(&self) -> bool {
515        self.is_terminated
516    }
517}
518
519impl fidl::endpoints::RequestStream for CommonRequestStream {
520    type Protocol = CommonMarker;
521    type ControlHandle = CommonControlHandle;
522
523    fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
524        Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
525    }
526
527    fn control_handle(&self) -> Self::ControlHandle {
528        CommonControlHandle { inner: self.inner.clone() }
529    }
530
531    fn into_inner(
532        self,
533    ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
534    {
535        (self.inner, self.is_terminated)
536    }
537
538    fn from_inner(
539        inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
540        is_terminated: bool,
541    ) -> Self {
542        Self { inner, is_terminated }
543    }
544}
545
546impl futures::Stream for CommonRequestStream {
547    type Item = Result<CommonRequest, fidl::Error>;
548
549    fn poll_next(
550        mut self: std::pin::Pin<&mut Self>,
551        cx: &mut std::task::Context<'_>,
552    ) -> std::task::Poll<Option<Self::Item>> {
553        let this = &mut *self;
554        if this.inner.check_shutdown(cx) {
555            this.is_terminated = true;
556            return std::task::Poll::Ready(None);
557        }
558        if this.is_terminated {
559            panic!("polled CommonRequestStream after completion");
560        }
561        fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
562            |bytes, handles| {
563                match this.inner.channel().read_etc(cx, bytes, handles) {
564                    std::task::Poll::Ready(Ok(())) => {}
565                    std::task::Poll::Pending => return std::task::Poll::Pending,
566                    std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
567                        this.is_terminated = true;
568                        return std::task::Poll::Ready(None);
569                    }
570                    std::task::Poll::Ready(Err(e)) => {
571                        return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
572                            e.into(),
573                        ))))
574                    }
575                }
576
577                // A message has been received from the channel
578                let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
579
580                std::task::Poll::Ready(Some(match header.ordinal {
581                    0x1551192b715c20b0 => {
582                        header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
583                        let mut req = fidl::new_empty!(
584                            fidl::encoding::EmptyPayload,
585                            fidl::encoding::DefaultFuchsiaResourceDialect
586                        );
587                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
588                        let control_handle = CommonControlHandle { inner: this.inner.clone() };
589                        Ok(CommonRequest::Query {
590                            responder: CommonQueryResponder {
591                                control_handle: std::mem::ManuallyDrop::new(control_handle),
592                                tx_id: header.tx_id,
593                            },
594                        })
595                    }
596                    0x4d57f58df2b01c6a => {
597                        header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
598                        let mut req = fidl::new_empty!(
599                            CommonQueueRequest,
600                            fidl::encoding::DefaultFuchsiaResourceDialect
601                        );
602                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<CommonQueueRequest>(&header, _body_bytes, handles, &mut req)?;
603                        let control_handle = CommonControlHandle { inner: this.inner.clone() };
604                        Ok(CommonRequest::Queue {
605                            txn: req.txn,
606
607                            responder: CommonQueueResponder {
608                                control_handle: std::mem::ManuallyDrop::new(control_handle),
609                                tx_id: header.tx_id,
610                            },
611                        })
612                    }
613                    _ => Err(fidl::Error::UnknownOrdinal {
614                        ordinal: header.ordinal,
615                        protocol_name:
616                            <CommonMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
617                    }),
618                }))
619            },
620        )
621    }
622}
623
624#[derive(Debug)]
625pub enum CommonRequest {
626    /// Obtains the parameters of the block device (`block_info_t`) and the
627    /// required size of `block_txn_t`. The `block_txn_t`s submitted via
628    /// `Queue()` must have `block_op_size_out - sizeof(block_op_t)` bytes
629    /// available at the end of the structure for the use of the driver.
630    Query { responder: CommonQueryResponder },
631    /// Submits an I/O request for processing. Ownership of `op` is transferred
632    /// to callee until `completion_cb` is invoked. Success or failure will be
633    /// reported via the `completion_cb`. This callback may be called before the
634    /// `Queue()` method returns.
635    Queue { txn: BlockOp, responder: CommonQueueResponder },
636}
637
638impl CommonRequest {
639    #[allow(irrefutable_let_patterns)]
640    pub fn into_query(self) -> Option<(CommonQueryResponder)> {
641        if let CommonRequest::Query { responder } = self {
642            Some((responder))
643        } else {
644            None
645        }
646    }
647
648    #[allow(irrefutable_let_patterns)]
649    pub fn into_queue(self) -> Option<(BlockOp, CommonQueueResponder)> {
650        if let CommonRequest::Queue { txn, responder } = self {
651            Some((txn, responder))
652        } else {
653            None
654        }
655    }
656
657    /// Name of the method defined in FIDL
658    pub fn method_name(&self) -> &'static str {
659        match *self {
660            CommonRequest::Query { .. } => "query",
661            CommonRequest::Queue { .. } => "queue",
662        }
663    }
664}
665
666#[derive(Debug, Clone)]
667pub struct CommonControlHandle {
668    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
669}
670
671impl fidl::endpoints::ControlHandle for CommonControlHandle {
672    fn shutdown(&self) {
673        self.inner.shutdown()
674    }
675    fn shutdown_with_epitaph(&self, status: zx_status::Status) {
676        self.inner.shutdown_with_epitaph(status)
677    }
678
679    fn is_closed(&self) -> bool {
680        self.inner.channel().is_closed()
681    }
682    fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
683        self.inner.channel().on_closed()
684    }
685
686    #[cfg(target_os = "fuchsia")]
687    fn signal_peer(
688        &self,
689        clear_mask: zx::Signals,
690        set_mask: zx::Signals,
691    ) -> Result<(), zx_status::Status> {
692        use fidl::Peered;
693        self.inner.channel().signal_peer(clear_mask, set_mask)
694    }
695}
696
697impl CommonControlHandle {}
698
699#[must_use = "FIDL methods require a response to be sent"]
700#[derive(Debug)]
701pub struct CommonQueryResponder {
702    control_handle: std::mem::ManuallyDrop<CommonControlHandle>,
703    tx_id: u32,
704}
705
706/// Set the the channel to be shutdown (see [`CommonControlHandle::shutdown`])
707/// if the responder is dropped without sending a response, so that the client
708/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
709impl std::ops::Drop for CommonQueryResponder {
710    fn drop(&mut self) {
711        self.control_handle.shutdown();
712        // Safety: drops once, never accessed again
713        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
714    }
715}
716
717impl fidl::endpoints::Responder for CommonQueryResponder {
718    type ControlHandle = CommonControlHandle;
719
720    fn control_handle(&self) -> &CommonControlHandle {
721        &self.control_handle
722    }
723
724    fn drop_without_shutdown(mut self) {
725        // Safety: drops once, never accessed again due to mem::forget
726        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
727        // Prevent Drop from running (which would shut down the channel)
728        std::mem::forget(self);
729    }
730}
731
732impl CommonQueryResponder {
733    /// Sends a response to the FIDL transaction.
734    ///
735    /// Sets the channel to shutdown if an error occurs.
736    pub fn send(
737        self,
738        mut info: &fidl_fuchsia_hardware_block::BlockInfo,
739        mut block_op_size: u64,
740    ) -> Result<(), fidl::Error> {
741        let _result = self.send_raw(info, block_op_size);
742        if _result.is_err() {
743            self.control_handle.shutdown();
744        }
745        self.drop_without_shutdown();
746        _result
747    }
748
749    /// Similar to "send" but does not shutdown the channel if an error occurs.
750    pub fn send_no_shutdown_on_err(
751        self,
752        mut info: &fidl_fuchsia_hardware_block::BlockInfo,
753        mut block_op_size: u64,
754    ) -> Result<(), fidl::Error> {
755        let _result = self.send_raw(info, block_op_size);
756        self.drop_without_shutdown();
757        _result
758    }
759
760    fn send_raw(
761        &self,
762        mut info: &fidl_fuchsia_hardware_block::BlockInfo,
763        mut block_op_size: u64,
764    ) -> Result<(), fidl::Error> {
765        self.control_handle.inner.send::<CommonQueryResponse>(
766            (info, block_op_size),
767            self.tx_id,
768            0x1551192b715c20b0,
769            fidl::encoding::DynamicFlags::empty(),
770        )
771    }
772}
773
774#[must_use = "FIDL methods require a response to be sent"]
775#[derive(Debug)]
776pub struct CommonQueueResponder {
777    control_handle: std::mem::ManuallyDrop<CommonControlHandle>,
778    tx_id: u32,
779}
780
781/// Set the the channel to be shutdown (see [`CommonControlHandle::shutdown`])
782/// if the responder is dropped without sending a response, so that the client
783/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
784impl std::ops::Drop for CommonQueueResponder {
785    fn drop(&mut self) {
786        self.control_handle.shutdown();
787        // Safety: drops once, never accessed again
788        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
789    }
790}
791
792impl fidl::endpoints::Responder for CommonQueueResponder {
793    type ControlHandle = CommonControlHandle;
794
795    fn control_handle(&self) -> &CommonControlHandle {
796        &self.control_handle
797    }
798
799    fn drop_without_shutdown(mut self) {
800        // Safety: drops once, never accessed again due to mem::forget
801        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
802        // Prevent Drop from running (which would shut down the channel)
803        std::mem::forget(self);
804    }
805}
806
807impl CommonQueueResponder {
808    /// Sends a response to the FIDL transaction.
809    ///
810    /// Sets the channel to shutdown if an error occurs.
811    pub fn send(self, mut status: i32, mut op: BlockOp) -> Result<(), fidl::Error> {
812        let _result = self.send_raw(status, op);
813        if _result.is_err() {
814            self.control_handle.shutdown();
815        }
816        self.drop_without_shutdown();
817        _result
818    }
819
820    /// Similar to "send" but does not shutdown the channel if an error occurs.
821    pub fn send_no_shutdown_on_err(
822        self,
823        mut status: i32,
824        mut op: BlockOp,
825    ) -> Result<(), fidl::Error> {
826        let _result = self.send_raw(status, op);
827        self.drop_without_shutdown();
828        _result
829    }
830
831    fn send_raw(&self, mut status: i32, mut op: BlockOp) -> Result<(), fidl::Error> {
832        self.control_handle.inner.send::<CommonQueueResponse>(
833            (status, &mut op),
834            self.tx_id,
835            0x4d57f58df2b01c6a,
836            fidl::encoding::DynamicFlags::empty(),
837        )
838    }
839}
840
841mod internal {
842    use super::*;
843    unsafe impl fidl::encoding::TypeMarker for BlockIoFlag {
844        type Owned = Self;
845
846        #[inline(always)]
847        fn inline_align(_context: fidl::encoding::Context) -> usize {
848            4
849        }
850
851        #[inline(always)]
852        fn inline_size(_context: fidl::encoding::Context) -> usize {
853            4
854        }
855    }
856
857    impl fidl::encoding::ValueTypeMarker for BlockIoFlag {
858        type Borrowed<'a> = Self;
859        #[inline(always)]
860        fn borrow(value: &<Self as fidl::encoding::TypeMarker>::Owned) -> Self::Borrowed<'_> {
861            *value
862        }
863    }
864
865    unsafe impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Encode<Self, D> for BlockIoFlag {
866        #[inline]
867        unsafe fn encode(
868            self,
869            encoder: &mut fidl::encoding::Encoder<'_, D>,
870            offset: usize,
871            _depth: fidl::encoding::Depth,
872        ) -> fidl::Result<()> {
873            encoder.debug_check_bounds::<Self>(offset);
874            if self.bits() & Self::all().bits() != self.bits() {
875                return Err(fidl::Error::InvalidBitsValue);
876            }
877            encoder.write_num(self.bits(), offset);
878            Ok(())
879        }
880    }
881
882    impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Decode<Self, D> for BlockIoFlag {
883        #[inline(always)]
884        fn new_empty() -> Self {
885            Self::empty()
886        }
887
888        #[inline]
889        unsafe fn decode(
890            &mut self,
891            decoder: &mut fidl::encoding::Decoder<'_, D>,
892            offset: usize,
893            _depth: fidl::encoding::Depth,
894        ) -> fidl::Result<()> {
895            decoder.debug_check_bounds::<Self>(offset);
896            let prim = decoder.read_num::<u32>(offset);
897            *self = Self::from_bits(prim).ok_or(fidl::Error::InvalidBitsValue)?;
898            Ok(())
899        }
900    }
901    unsafe impl fidl::encoding::TypeMarker for BlockOpcode {
902        type Owned = Self;
903
904        #[inline(always)]
905        fn inline_align(_context: fidl::encoding::Context) -> usize {
906            std::mem::align_of::<u8>()
907        }
908
909        #[inline(always)]
910        fn inline_size(_context: fidl::encoding::Context) -> usize {
911            std::mem::size_of::<u8>()
912        }
913
914        #[inline(always)]
915        fn encode_is_copy() -> bool {
916            true
917        }
918
919        #[inline(always)]
920        fn decode_is_copy() -> bool {
921            false
922        }
923    }
924
925    impl fidl::encoding::ValueTypeMarker for BlockOpcode {
926        type Borrowed<'a> = Self;
927        #[inline(always)]
928        fn borrow(value: &<Self as fidl::encoding::TypeMarker>::Owned) -> Self::Borrowed<'_> {
929            *value
930        }
931    }
932
933    unsafe impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Encode<Self, D> for BlockOpcode {
934        #[inline]
935        unsafe fn encode(
936            self,
937            encoder: &mut fidl::encoding::Encoder<'_, D>,
938            offset: usize,
939            _depth: fidl::encoding::Depth,
940        ) -> fidl::Result<()> {
941            encoder.debug_check_bounds::<Self>(offset);
942            encoder.write_num(self.into_primitive(), offset);
943            Ok(())
944        }
945    }
946
947    impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Decode<Self, D> for BlockOpcode {
948        #[inline(always)]
949        fn new_empty() -> Self {
950            Self::Read
951        }
952
953        #[inline]
954        unsafe fn decode(
955            &mut self,
956            decoder: &mut fidl::encoding::Decoder<'_, D>,
957            offset: usize,
958            _depth: fidl::encoding::Depth,
959        ) -> fidl::Result<()> {
960            decoder.debug_check_bounds::<Self>(offset);
961            let prim = decoder.read_num::<u8>(offset);
962
963            *self = Self::from_primitive(prim).ok_or(fidl::Error::InvalidEnumValue)?;
964            Ok(())
965        }
966    }
967
968    impl fidl::encoding::ValueTypeMarker for BlockCommand {
969        type Borrowed<'a> = &'a Self;
970        fn borrow(value: &<Self as fidl::encoding::TypeMarker>::Owned) -> Self::Borrowed<'_> {
971            value
972        }
973    }
974
975    unsafe impl fidl::encoding::TypeMarker for BlockCommand {
976        type Owned = Self;
977
978        #[inline(always)]
979        fn inline_align(_context: fidl::encoding::Context) -> usize {
980            4
981        }
982
983        #[inline(always)]
984        fn inline_size(_context: fidl::encoding::Context) -> usize {
985            8
986        }
987    }
988
989    unsafe impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Encode<BlockCommand, D>
990        for &BlockCommand
991    {
992        #[inline]
993        unsafe fn encode(
994            self,
995            encoder: &mut fidl::encoding::Encoder<'_, D>,
996            offset: usize,
997            _depth: fidl::encoding::Depth,
998        ) -> fidl::Result<()> {
999            encoder.debug_check_bounds::<BlockCommand>(offset);
1000            // Delegate to tuple encoding.
1001            fidl::encoding::Encode::<BlockCommand, D>::encode(
1002                (
1003                    <BlockOpcode as fidl::encoding::ValueTypeMarker>::borrow(&self.opcode),
1004                    <BlockIoFlag as fidl::encoding::ValueTypeMarker>::borrow(&self.flags),
1005                ),
1006                encoder,
1007                offset,
1008                _depth,
1009            )
1010        }
1011    }
1012    unsafe impl<
1013            D: fidl::encoding::ResourceDialect,
1014            T0: fidl::encoding::Encode<BlockOpcode, D>,
1015            T1: fidl::encoding::Encode<BlockIoFlag, D>,
1016        > fidl::encoding::Encode<BlockCommand, D> for (T0, T1)
1017    {
1018        #[inline]
1019        unsafe fn encode(
1020            self,
1021            encoder: &mut fidl::encoding::Encoder<'_, D>,
1022            offset: usize,
1023            depth: fidl::encoding::Depth,
1024        ) -> fidl::Result<()> {
1025            encoder.debug_check_bounds::<BlockCommand>(offset);
1026            // Zero out padding regions. There's no need to apply masks
1027            // because the unmasked parts will be overwritten by fields.
1028            unsafe {
1029                let ptr = encoder.buf.as_mut_ptr().add(offset).offset(0);
1030                (ptr as *mut u32).write_unaligned(0);
1031            }
1032            // Write the fields.
1033            self.0.encode(encoder, offset + 0, depth)?;
1034            self.1.encode(encoder, offset + 4, depth)?;
1035            Ok(())
1036        }
1037    }
1038
1039    impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Decode<Self, D> for BlockCommand {
1040        #[inline(always)]
1041        fn new_empty() -> Self {
1042            Self {
1043                opcode: fidl::new_empty!(BlockOpcode, D),
1044                flags: fidl::new_empty!(BlockIoFlag, D),
1045            }
1046        }
1047
1048        #[inline]
1049        unsafe fn decode(
1050            &mut self,
1051            decoder: &mut fidl::encoding::Decoder<'_, D>,
1052            offset: usize,
1053            _depth: fidl::encoding::Depth,
1054        ) -> fidl::Result<()> {
1055            decoder.debug_check_bounds::<Self>(offset);
1056            // Verify that padding bytes are zero.
1057            let ptr = unsafe { decoder.buf.as_ptr().add(offset).offset(0) };
1058            let padval = unsafe { (ptr as *const u32).read_unaligned() };
1059            let mask = 0xffffff00u32;
1060            let maskedval = padval & mask;
1061            if maskedval != 0 {
1062                return Err(fidl::Error::NonZeroPadding {
1063                    padding_start: offset + 0 + ((mask as u64).trailing_zeros() / 8) as usize,
1064                });
1065            }
1066            fidl::decode!(BlockOpcode, D, &mut self.opcode, decoder, offset + 0, _depth)?;
1067            fidl::decode!(BlockIoFlag, D, &mut self.flags, decoder, offset + 4, _depth)?;
1068            Ok(())
1069        }
1070    }
1071
1072    impl fidl::encoding::ResourceTypeMarker for BlockReadWrite {
1073        type Borrowed<'a> = &'a mut Self;
1074        fn take_or_borrow<'a>(
1075            value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
1076        ) -> Self::Borrowed<'a> {
1077            value
1078        }
1079    }
1080
1081    unsafe impl fidl::encoding::TypeMarker for BlockReadWrite {
1082        type Owned = Self;
1083
1084        #[inline(always)]
1085        fn inline_align(_context: fidl::encoding::Context) -> usize {
1086            8
1087        }
1088
1089        #[inline(always)]
1090        fn inline_size(_context: fidl::encoding::Context) -> usize {
1091            40
1092        }
1093    }
1094
1095    unsafe impl
1096        fidl::encoding::Encode<BlockReadWrite, fidl::encoding::DefaultFuchsiaResourceDialect>
1097        for &mut BlockReadWrite
1098    {
1099        #[inline]
1100        unsafe fn encode(
1101            self,
1102            encoder: &mut fidl::encoding::Encoder<
1103                '_,
1104                fidl::encoding::DefaultFuchsiaResourceDialect,
1105            >,
1106            offset: usize,
1107            _depth: fidl::encoding::Depth,
1108        ) -> fidl::Result<()> {
1109            encoder.debug_check_bounds::<BlockReadWrite>(offset);
1110            // Delegate to tuple encoding.
1111            fidl::encoding::Encode::<BlockReadWrite, fidl::encoding::DefaultFuchsiaResourceDialect>::encode(
1112                (
1113                    <BlockCommand as fidl::encoding::ValueTypeMarker>::borrow(&self.command),
1114                    <u32 as fidl::encoding::ValueTypeMarker>::borrow(&self.extra),
1115                    <fidl::encoding::HandleType<fidl::Vmo, { fidl::ObjectType::VMO.into_raw() }, 2147483648> as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.vmo),
1116                    <u32 as fidl::encoding::ValueTypeMarker>::borrow(&self.length),
1117                    <u64 as fidl::encoding::ValueTypeMarker>::borrow(&self.offset_dev),
1118                    <u64 as fidl::encoding::ValueTypeMarker>::borrow(&self.offset_vmo),
1119                ),
1120                encoder, offset, _depth
1121            )
1122        }
1123    }
1124    unsafe impl<
1125            T0: fidl::encoding::Encode<BlockCommand, fidl::encoding::DefaultFuchsiaResourceDialect>,
1126            T1: fidl::encoding::Encode<u32, fidl::encoding::DefaultFuchsiaResourceDialect>,
1127            T2: fidl::encoding::Encode<
1128                fidl::encoding::HandleType<
1129                    fidl::Vmo,
1130                    { fidl::ObjectType::VMO.into_raw() },
1131                    2147483648,
1132                >,
1133                fidl::encoding::DefaultFuchsiaResourceDialect,
1134            >,
1135            T3: fidl::encoding::Encode<u32, fidl::encoding::DefaultFuchsiaResourceDialect>,
1136            T4: fidl::encoding::Encode<u64, fidl::encoding::DefaultFuchsiaResourceDialect>,
1137            T5: fidl::encoding::Encode<u64, fidl::encoding::DefaultFuchsiaResourceDialect>,
1138        > fidl::encoding::Encode<BlockReadWrite, fidl::encoding::DefaultFuchsiaResourceDialect>
1139        for (T0, T1, T2, T3, T4, T5)
1140    {
1141        #[inline]
1142        unsafe fn encode(
1143            self,
1144            encoder: &mut fidl::encoding::Encoder<
1145                '_,
1146                fidl::encoding::DefaultFuchsiaResourceDialect,
1147            >,
1148            offset: usize,
1149            depth: fidl::encoding::Depth,
1150        ) -> fidl::Result<()> {
1151            encoder.debug_check_bounds::<BlockReadWrite>(offset);
1152            // Zero out padding regions. There's no need to apply masks
1153            // because the unmasked parts will be overwritten by fields.
1154            unsafe {
1155                let ptr = encoder.buf.as_mut_ptr().add(offset).offset(16);
1156                (ptr as *mut u64).write_unaligned(0);
1157            }
1158            // Write the fields.
1159            self.0.encode(encoder, offset + 0, depth)?;
1160            self.1.encode(encoder, offset + 8, depth)?;
1161            self.2.encode(encoder, offset + 12, depth)?;
1162            self.3.encode(encoder, offset + 16, depth)?;
1163            self.4.encode(encoder, offset + 24, depth)?;
1164            self.5.encode(encoder, offset + 32, depth)?;
1165            Ok(())
1166        }
1167    }
1168
1169    impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
1170        for BlockReadWrite
1171    {
1172        #[inline(always)]
1173        fn new_empty() -> Self {
1174            Self {
1175                command: fidl::new_empty!(
1176                    BlockCommand,
1177                    fidl::encoding::DefaultFuchsiaResourceDialect
1178                ),
1179                extra: fidl::new_empty!(u32, fidl::encoding::DefaultFuchsiaResourceDialect),
1180                vmo: fidl::new_empty!(fidl::encoding::HandleType<fidl::Vmo, { fidl::ObjectType::VMO.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect),
1181                length: fidl::new_empty!(u32, fidl::encoding::DefaultFuchsiaResourceDialect),
1182                offset_dev: fidl::new_empty!(u64, fidl::encoding::DefaultFuchsiaResourceDialect),
1183                offset_vmo: fidl::new_empty!(u64, fidl::encoding::DefaultFuchsiaResourceDialect),
1184            }
1185        }
1186
1187        #[inline]
1188        unsafe fn decode(
1189            &mut self,
1190            decoder: &mut fidl::encoding::Decoder<
1191                '_,
1192                fidl::encoding::DefaultFuchsiaResourceDialect,
1193            >,
1194            offset: usize,
1195            _depth: fidl::encoding::Depth,
1196        ) -> fidl::Result<()> {
1197            decoder.debug_check_bounds::<Self>(offset);
1198            // Verify that padding bytes are zero.
1199            let ptr = unsafe { decoder.buf.as_ptr().add(offset).offset(16) };
1200            let padval = unsafe { (ptr as *const u64).read_unaligned() };
1201            let mask = 0xffffffff00000000u64;
1202            let maskedval = padval & mask;
1203            if maskedval != 0 {
1204                return Err(fidl::Error::NonZeroPadding {
1205                    padding_start: offset + 16 + ((mask as u64).trailing_zeros() / 8) as usize,
1206                });
1207            }
1208            fidl::decode!(
1209                BlockCommand,
1210                fidl::encoding::DefaultFuchsiaResourceDialect,
1211                &mut self.command,
1212                decoder,
1213                offset + 0,
1214                _depth
1215            )?;
1216            fidl::decode!(
1217                u32,
1218                fidl::encoding::DefaultFuchsiaResourceDialect,
1219                &mut self.extra,
1220                decoder,
1221                offset + 8,
1222                _depth
1223            )?;
1224            fidl::decode!(fidl::encoding::HandleType<fidl::Vmo, { fidl::ObjectType::VMO.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, &mut self.vmo, decoder, offset + 12, _depth)?;
1225            fidl::decode!(
1226                u32,
1227                fidl::encoding::DefaultFuchsiaResourceDialect,
1228                &mut self.length,
1229                decoder,
1230                offset + 16,
1231                _depth
1232            )?;
1233            fidl::decode!(
1234                u64,
1235                fidl::encoding::DefaultFuchsiaResourceDialect,
1236                &mut self.offset_dev,
1237                decoder,
1238                offset + 24,
1239                _depth
1240            )?;
1241            fidl::decode!(
1242                u64,
1243                fidl::encoding::DefaultFuchsiaResourceDialect,
1244                &mut self.offset_vmo,
1245                decoder,
1246                offset + 32,
1247                _depth
1248            )?;
1249            Ok(())
1250        }
1251    }
1252
1253    impl fidl::encoding::ValueTypeMarker for BlockTrim {
1254        type Borrowed<'a> = &'a Self;
1255        fn borrow(value: &<Self as fidl::encoding::TypeMarker>::Owned) -> Self::Borrowed<'_> {
1256            value
1257        }
1258    }
1259
1260    unsafe impl fidl::encoding::TypeMarker for BlockTrim {
1261        type Owned = Self;
1262
1263        #[inline(always)]
1264        fn inline_align(_context: fidl::encoding::Context) -> usize {
1265            8
1266        }
1267
1268        #[inline(always)]
1269        fn inline_size(_context: fidl::encoding::Context) -> usize {
1270            24
1271        }
1272    }
1273
1274    unsafe impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Encode<BlockTrim, D>
1275        for &BlockTrim
1276    {
1277        #[inline]
1278        unsafe fn encode(
1279            self,
1280            encoder: &mut fidl::encoding::Encoder<'_, D>,
1281            offset: usize,
1282            _depth: fidl::encoding::Depth,
1283        ) -> fidl::Result<()> {
1284            encoder.debug_check_bounds::<BlockTrim>(offset);
1285            // Delegate to tuple encoding.
1286            fidl::encoding::Encode::<BlockTrim, D>::encode(
1287                (
1288                    <BlockCommand as fidl::encoding::ValueTypeMarker>::borrow(&self.command),
1289                    <u32 as fidl::encoding::ValueTypeMarker>::borrow(&self.length),
1290                    <u64 as fidl::encoding::ValueTypeMarker>::borrow(&self.offset_dev),
1291                ),
1292                encoder,
1293                offset,
1294                _depth,
1295            )
1296        }
1297    }
1298    unsafe impl<
1299            D: fidl::encoding::ResourceDialect,
1300            T0: fidl::encoding::Encode<BlockCommand, D>,
1301            T1: fidl::encoding::Encode<u32, D>,
1302            T2: fidl::encoding::Encode<u64, D>,
1303        > fidl::encoding::Encode<BlockTrim, D> for (T0, T1, T2)
1304    {
1305        #[inline]
1306        unsafe fn encode(
1307            self,
1308            encoder: &mut fidl::encoding::Encoder<'_, D>,
1309            offset: usize,
1310            depth: fidl::encoding::Depth,
1311        ) -> fidl::Result<()> {
1312            encoder.debug_check_bounds::<BlockTrim>(offset);
1313            // Zero out padding regions. There's no need to apply masks
1314            // because the unmasked parts will be overwritten by fields.
1315            unsafe {
1316                let ptr = encoder.buf.as_mut_ptr().add(offset).offset(8);
1317                (ptr as *mut u64).write_unaligned(0);
1318            }
1319            // Write the fields.
1320            self.0.encode(encoder, offset + 0, depth)?;
1321            self.1.encode(encoder, offset + 8, depth)?;
1322            self.2.encode(encoder, offset + 16, depth)?;
1323            Ok(())
1324        }
1325    }
1326
1327    impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Decode<Self, D> for BlockTrim {
1328        #[inline(always)]
1329        fn new_empty() -> Self {
1330            Self {
1331                command: fidl::new_empty!(BlockCommand, D),
1332                length: fidl::new_empty!(u32, D),
1333                offset_dev: fidl::new_empty!(u64, D),
1334            }
1335        }
1336
1337        #[inline]
1338        unsafe fn decode(
1339            &mut self,
1340            decoder: &mut fidl::encoding::Decoder<'_, D>,
1341            offset: usize,
1342            _depth: fidl::encoding::Depth,
1343        ) -> fidl::Result<()> {
1344            decoder.debug_check_bounds::<Self>(offset);
1345            // Verify that padding bytes are zero.
1346            let ptr = unsafe { decoder.buf.as_ptr().add(offset).offset(8) };
1347            let padval = unsafe { (ptr as *const u64).read_unaligned() };
1348            let mask = 0xffffffff00000000u64;
1349            let maskedval = padval & mask;
1350            if maskedval != 0 {
1351                return Err(fidl::Error::NonZeroPadding {
1352                    padding_start: offset + 8 + ((mask as u64).trailing_zeros() / 8) as usize,
1353                });
1354            }
1355            fidl::decode!(BlockCommand, D, &mut self.command, decoder, offset + 0, _depth)?;
1356            fidl::decode!(u32, D, &mut self.length, decoder, offset + 8, _depth)?;
1357            fidl::decode!(u64, D, &mut self.offset_dev, decoder, offset + 16, _depth)?;
1358            Ok(())
1359        }
1360    }
1361
1362    impl fidl::encoding::ValueTypeMarker for CommonQueryResponse {
1363        type Borrowed<'a> = &'a Self;
1364        fn borrow(value: &<Self as fidl::encoding::TypeMarker>::Owned) -> Self::Borrowed<'_> {
1365            value
1366        }
1367    }
1368
1369    unsafe impl fidl::encoding::TypeMarker for CommonQueryResponse {
1370        type Owned = Self;
1371
1372        #[inline(always)]
1373        fn inline_align(_context: fidl::encoding::Context) -> usize {
1374            8
1375        }
1376
1377        #[inline(always)]
1378        fn inline_size(_context: fidl::encoding::Context) -> usize {
1379            32
1380        }
1381    }
1382
1383    unsafe impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Encode<CommonQueryResponse, D>
1384        for &CommonQueryResponse
1385    {
1386        #[inline]
1387        unsafe fn encode(
1388            self,
1389            encoder: &mut fidl::encoding::Encoder<'_, D>,
1390            offset: usize,
1391            _depth: fidl::encoding::Depth,
1392        ) -> fidl::Result<()> {
1393            encoder.debug_check_bounds::<CommonQueryResponse>(offset);
1394            // Delegate to tuple encoding.
1395            fidl::encoding::Encode::<CommonQueryResponse, D>::encode(
1396                (
1397                    <fidl_fuchsia_hardware_block::BlockInfo as fidl::encoding::ValueTypeMarker>::borrow(&self.info),
1398                    <u64 as fidl::encoding::ValueTypeMarker>::borrow(&self.block_op_size),
1399                ),
1400                encoder, offset, _depth
1401            )
1402        }
1403    }
1404    unsafe impl<
1405            D: fidl::encoding::ResourceDialect,
1406            T0: fidl::encoding::Encode<fidl_fuchsia_hardware_block::BlockInfo, D>,
1407            T1: fidl::encoding::Encode<u64, D>,
1408        > fidl::encoding::Encode<CommonQueryResponse, D> for (T0, T1)
1409    {
1410        #[inline]
1411        unsafe fn encode(
1412            self,
1413            encoder: &mut fidl::encoding::Encoder<'_, D>,
1414            offset: usize,
1415            depth: fidl::encoding::Depth,
1416        ) -> fidl::Result<()> {
1417            encoder.debug_check_bounds::<CommonQueryResponse>(offset);
1418            // Zero out padding regions. There's no need to apply masks
1419            // because the unmasked parts will be overwritten by fields.
1420            // Write the fields.
1421            self.0.encode(encoder, offset + 0, depth)?;
1422            self.1.encode(encoder, offset + 24, depth)?;
1423            Ok(())
1424        }
1425    }
1426
1427    impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Decode<Self, D> for CommonQueryResponse {
1428        #[inline(always)]
1429        fn new_empty() -> Self {
1430            Self {
1431                info: fidl::new_empty!(fidl_fuchsia_hardware_block::BlockInfo, D),
1432                block_op_size: fidl::new_empty!(u64, D),
1433            }
1434        }
1435
1436        #[inline]
1437        unsafe fn decode(
1438            &mut self,
1439            decoder: &mut fidl::encoding::Decoder<'_, D>,
1440            offset: usize,
1441            _depth: fidl::encoding::Depth,
1442        ) -> fidl::Result<()> {
1443            decoder.debug_check_bounds::<Self>(offset);
1444            // Verify that padding bytes are zero.
1445            fidl::decode!(
1446                fidl_fuchsia_hardware_block::BlockInfo,
1447                D,
1448                &mut self.info,
1449                decoder,
1450                offset + 0,
1451                _depth
1452            )?;
1453            fidl::decode!(u64, D, &mut self.block_op_size, decoder, offset + 24, _depth)?;
1454            Ok(())
1455        }
1456    }
1457
1458    impl fidl::encoding::ResourceTypeMarker for CommonQueueRequest {
1459        type Borrowed<'a> = &'a mut Self;
1460        fn take_or_borrow<'a>(
1461            value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
1462        ) -> Self::Borrowed<'a> {
1463            value
1464        }
1465    }
1466
1467    unsafe impl fidl::encoding::TypeMarker for CommonQueueRequest {
1468        type Owned = Self;
1469
1470        #[inline(always)]
1471        fn inline_align(_context: fidl::encoding::Context) -> usize {
1472            8
1473        }
1474
1475        #[inline(always)]
1476        fn inline_size(_context: fidl::encoding::Context) -> usize {
1477            16
1478        }
1479    }
1480
1481    unsafe impl
1482        fidl::encoding::Encode<CommonQueueRequest, fidl::encoding::DefaultFuchsiaResourceDialect>
1483        for &mut CommonQueueRequest
1484    {
1485        #[inline]
1486        unsafe fn encode(
1487            self,
1488            encoder: &mut fidl::encoding::Encoder<
1489                '_,
1490                fidl::encoding::DefaultFuchsiaResourceDialect,
1491            >,
1492            offset: usize,
1493            _depth: fidl::encoding::Depth,
1494        ) -> fidl::Result<()> {
1495            encoder.debug_check_bounds::<CommonQueueRequest>(offset);
1496            // Delegate to tuple encoding.
1497            fidl::encoding::Encode::<
1498                CommonQueueRequest,
1499                fidl::encoding::DefaultFuchsiaResourceDialect,
1500            >::encode(
1501                (<BlockOp as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.txn),),
1502                encoder,
1503                offset,
1504                _depth,
1505            )
1506        }
1507    }
1508    unsafe impl<T0: fidl::encoding::Encode<BlockOp, fidl::encoding::DefaultFuchsiaResourceDialect>>
1509        fidl::encoding::Encode<CommonQueueRequest, fidl::encoding::DefaultFuchsiaResourceDialect>
1510        for (T0,)
1511    {
1512        #[inline]
1513        unsafe fn encode(
1514            self,
1515            encoder: &mut fidl::encoding::Encoder<
1516                '_,
1517                fidl::encoding::DefaultFuchsiaResourceDialect,
1518            >,
1519            offset: usize,
1520            depth: fidl::encoding::Depth,
1521        ) -> fidl::Result<()> {
1522            encoder.debug_check_bounds::<CommonQueueRequest>(offset);
1523            // Zero out padding regions. There's no need to apply masks
1524            // because the unmasked parts will be overwritten by fields.
1525            // Write the fields.
1526            self.0.encode(encoder, offset + 0, depth)?;
1527            Ok(())
1528        }
1529    }
1530
1531    impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
1532        for CommonQueueRequest
1533    {
1534        #[inline(always)]
1535        fn new_empty() -> Self {
1536            Self { txn: fidl::new_empty!(BlockOp, fidl::encoding::DefaultFuchsiaResourceDialect) }
1537        }
1538
1539        #[inline]
1540        unsafe fn decode(
1541            &mut self,
1542            decoder: &mut fidl::encoding::Decoder<
1543                '_,
1544                fidl::encoding::DefaultFuchsiaResourceDialect,
1545            >,
1546            offset: usize,
1547            _depth: fidl::encoding::Depth,
1548        ) -> fidl::Result<()> {
1549            decoder.debug_check_bounds::<Self>(offset);
1550            // Verify that padding bytes are zero.
1551            fidl::decode!(
1552                BlockOp,
1553                fidl::encoding::DefaultFuchsiaResourceDialect,
1554                &mut self.txn,
1555                decoder,
1556                offset + 0,
1557                _depth
1558            )?;
1559            Ok(())
1560        }
1561    }
1562
1563    impl fidl::encoding::ResourceTypeMarker for CommonQueueResponse {
1564        type Borrowed<'a> = &'a mut Self;
1565        fn take_or_borrow<'a>(
1566            value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
1567        ) -> Self::Borrowed<'a> {
1568            value
1569        }
1570    }
1571
1572    unsafe impl fidl::encoding::TypeMarker for CommonQueueResponse {
1573        type Owned = Self;
1574
1575        #[inline(always)]
1576        fn inline_align(_context: fidl::encoding::Context) -> usize {
1577            8
1578        }
1579
1580        #[inline(always)]
1581        fn inline_size(_context: fidl::encoding::Context) -> usize {
1582            24
1583        }
1584    }
1585
1586    unsafe impl
1587        fidl::encoding::Encode<CommonQueueResponse, fidl::encoding::DefaultFuchsiaResourceDialect>
1588        for &mut CommonQueueResponse
1589    {
1590        #[inline]
1591        unsafe fn encode(
1592            self,
1593            encoder: &mut fidl::encoding::Encoder<
1594                '_,
1595                fidl::encoding::DefaultFuchsiaResourceDialect,
1596            >,
1597            offset: usize,
1598            _depth: fidl::encoding::Depth,
1599        ) -> fidl::Result<()> {
1600            encoder.debug_check_bounds::<CommonQueueResponse>(offset);
1601            // Delegate to tuple encoding.
1602            fidl::encoding::Encode::<
1603                CommonQueueResponse,
1604                fidl::encoding::DefaultFuchsiaResourceDialect,
1605            >::encode(
1606                (
1607                    <i32 as fidl::encoding::ValueTypeMarker>::borrow(&self.status),
1608                    <BlockOp as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.op),
1609                ),
1610                encoder,
1611                offset,
1612                _depth,
1613            )
1614        }
1615    }
1616    unsafe impl<
1617            T0: fidl::encoding::Encode<i32, fidl::encoding::DefaultFuchsiaResourceDialect>,
1618            T1: fidl::encoding::Encode<BlockOp, fidl::encoding::DefaultFuchsiaResourceDialect>,
1619        >
1620        fidl::encoding::Encode<CommonQueueResponse, fidl::encoding::DefaultFuchsiaResourceDialect>
1621        for (T0, T1)
1622    {
1623        #[inline]
1624        unsafe fn encode(
1625            self,
1626            encoder: &mut fidl::encoding::Encoder<
1627                '_,
1628                fidl::encoding::DefaultFuchsiaResourceDialect,
1629            >,
1630            offset: usize,
1631            depth: fidl::encoding::Depth,
1632        ) -> fidl::Result<()> {
1633            encoder.debug_check_bounds::<CommonQueueResponse>(offset);
1634            // Zero out padding regions. There's no need to apply masks
1635            // because the unmasked parts will be overwritten by fields.
1636            unsafe {
1637                let ptr = encoder.buf.as_mut_ptr().add(offset).offset(0);
1638                (ptr as *mut u64).write_unaligned(0);
1639            }
1640            // Write the fields.
1641            self.0.encode(encoder, offset + 0, depth)?;
1642            self.1.encode(encoder, offset + 8, depth)?;
1643            Ok(())
1644        }
1645    }
1646
1647    impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
1648        for CommonQueueResponse
1649    {
1650        #[inline(always)]
1651        fn new_empty() -> Self {
1652            Self {
1653                status: fidl::new_empty!(i32, fidl::encoding::DefaultFuchsiaResourceDialect),
1654                op: fidl::new_empty!(BlockOp, fidl::encoding::DefaultFuchsiaResourceDialect),
1655            }
1656        }
1657
1658        #[inline]
1659        unsafe fn decode(
1660            &mut self,
1661            decoder: &mut fidl::encoding::Decoder<
1662                '_,
1663                fidl::encoding::DefaultFuchsiaResourceDialect,
1664            >,
1665            offset: usize,
1666            _depth: fidl::encoding::Depth,
1667        ) -> fidl::Result<()> {
1668            decoder.debug_check_bounds::<Self>(offset);
1669            // Verify that padding bytes are zero.
1670            let ptr = unsafe { decoder.buf.as_ptr().add(offset).offset(0) };
1671            let padval = unsafe { (ptr as *const u64).read_unaligned() };
1672            let mask = 0xffffffff00000000u64;
1673            let maskedval = padval & mask;
1674            if maskedval != 0 {
1675                return Err(fidl::Error::NonZeroPadding {
1676                    padding_start: offset + 0 + ((mask as u64).trailing_zeros() / 8) as usize,
1677                });
1678            }
1679            fidl::decode!(
1680                i32,
1681                fidl::encoding::DefaultFuchsiaResourceDialect,
1682                &mut self.status,
1683                decoder,
1684                offset + 0,
1685                _depth
1686            )?;
1687            fidl::decode!(
1688                BlockOp,
1689                fidl::encoding::DefaultFuchsiaResourceDialect,
1690                &mut self.op,
1691                decoder,
1692                offset + 8,
1693                _depth
1694            )?;
1695            Ok(())
1696        }
1697    }
1698
1699    impl fidl::encoding::ResourceTypeMarker for BlockOp {
1700        type Borrowed<'a> = &'a mut Self;
1701        fn take_or_borrow<'a>(
1702            value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
1703        ) -> Self::Borrowed<'a> {
1704            value
1705        }
1706    }
1707
1708    unsafe impl fidl::encoding::TypeMarker for BlockOp {
1709        type Owned = Self;
1710
1711        #[inline(always)]
1712        fn inline_align(_context: fidl::encoding::Context) -> usize {
1713            8
1714        }
1715
1716        #[inline(always)]
1717        fn inline_size(_context: fidl::encoding::Context) -> usize {
1718            16
1719        }
1720    }
1721
1722    unsafe impl fidl::encoding::Encode<BlockOp, fidl::encoding::DefaultFuchsiaResourceDialect>
1723        for &mut BlockOp
1724    {
1725        #[inline]
1726        unsafe fn encode(
1727            self,
1728            encoder: &mut fidl::encoding::Encoder<
1729                '_,
1730                fidl::encoding::DefaultFuchsiaResourceDialect,
1731            >,
1732            offset: usize,
1733            _depth: fidl::encoding::Depth,
1734        ) -> fidl::Result<()> {
1735            encoder.debug_check_bounds::<BlockOp>(offset);
1736            encoder.write_num::<u64>(self.ordinal(), offset);
1737            match self {
1738                BlockOp::Command(ref val) => fidl::encoding::encode_in_envelope::<
1739                    BlockCommand,
1740                    fidl::encoding::DefaultFuchsiaResourceDialect,
1741                >(
1742                    <BlockCommand as fidl::encoding::ValueTypeMarker>::borrow(val),
1743                    encoder,
1744                    offset + 8,
1745                    _depth,
1746                ),
1747                BlockOp::Rw(ref mut val) => fidl::encoding::encode_in_envelope::<
1748                    BlockReadWrite,
1749                    fidl::encoding::DefaultFuchsiaResourceDialect,
1750                >(
1751                    <BlockReadWrite as fidl::encoding::ResourceTypeMarker>::take_or_borrow(val),
1752                    encoder,
1753                    offset + 8,
1754                    _depth,
1755                ),
1756                BlockOp::Trim(ref val) => fidl::encoding::encode_in_envelope::<
1757                    BlockTrim,
1758                    fidl::encoding::DefaultFuchsiaResourceDialect,
1759                >(
1760                    <BlockTrim as fidl::encoding::ValueTypeMarker>::borrow(val),
1761                    encoder,
1762                    offset + 8,
1763                    _depth,
1764                ),
1765            }
1766        }
1767    }
1768
1769    impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect> for BlockOp {
1770        #[inline(always)]
1771        fn new_empty() -> Self {
1772            Self::Command(fidl::new_empty!(
1773                BlockCommand,
1774                fidl::encoding::DefaultFuchsiaResourceDialect
1775            ))
1776        }
1777
1778        #[inline]
1779        unsafe fn decode(
1780            &mut self,
1781            decoder: &mut fidl::encoding::Decoder<
1782                '_,
1783                fidl::encoding::DefaultFuchsiaResourceDialect,
1784            >,
1785            offset: usize,
1786            mut depth: fidl::encoding::Depth,
1787        ) -> fidl::Result<()> {
1788            decoder.debug_check_bounds::<Self>(offset);
1789            #[allow(unused_variables)]
1790            let next_out_of_line = decoder.next_out_of_line();
1791            let handles_before = decoder.remaining_handles();
1792            let (ordinal, inlined, num_bytes, num_handles) =
1793                fidl::encoding::decode_union_inline_portion(decoder, offset)?;
1794
1795            let member_inline_size = match ordinal {
1796                1 => <BlockCommand as fidl::encoding::TypeMarker>::inline_size(decoder.context),
1797                2 => <BlockReadWrite as fidl::encoding::TypeMarker>::inline_size(decoder.context),
1798                3 => <BlockTrim as fidl::encoding::TypeMarker>::inline_size(decoder.context),
1799                _ => return Err(fidl::Error::UnknownUnionTag),
1800            };
1801
1802            if inlined != (member_inline_size <= 4) {
1803                return Err(fidl::Error::InvalidInlineBitInEnvelope);
1804            }
1805            let _inner_offset;
1806            if inlined {
1807                decoder.check_inline_envelope_padding(offset + 8, member_inline_size)?;
1808                _inner_offset = offset + 8;
1809            } else {
1810                depth.increment()?;
1811                _inner_offset = decoder.out_of_line_offset(member_inline_size)?;
1812            }
1813            match ordinal {
1814                1 => {
1815                    #[allow(irrefutable_let_patterns)]
1816                    if let BlockOp::Command(_) = self {
1817                        // Do nothing, read the value into the object
1818                    } else {
1819                        // Initialize `self` to the right variant
1820                        *self = BlockOp::Command(fidl::new_empty!(
1821                            BlockCommand,
1822                            fidl::encoding::DefaultFuchsiaResourceDialect
1823                        ));
1824                    }
1825                    #[allow(irrefutable_let_patterns)]
1826                    if let BlockOp::Command(ref mut val) = self {
1827                        fidl::decode!(
1828                            BlockCommand,
1829                            fidl::encoding::DefaultFuchsiaResourceDialect,
1830                            val,
1831                            decoder,
1832                            _inner_offset,
1833                            depth
1834                        )?;
1835                    } else {
1836                        unreachable!()
1837                    }
1838                }
1839                2 => {
1840                    #[allow(irrefutable_let_patterns)]
1841                    if let BlockOp::Rw(_) = self {
1842                        // Do nothing, read the value into the object
1843                    } else {
1844                        // Initialize `self` to the right variant
1845                        *self = BlockOp::Rw(fidl::new_empty!(
1846                            BlockReadWrite,
1847                            fidl::encoding::DefaultFuchsiaResourceDialect
1848                        ));
1849                    }
1850                    #[allow(irrefutable_let_patterns)]
1851                    if let BlockOp::Rw(ref mut val) = self {
1852                        fidl::decode!(
1853                            BlockReadWrite,
1854                            fidl::encoding::DefaultFuchsiaResourceDialect,
1855                            val,
1856                            decoder,
1857                            _inner_offset,
1858                            depth
1859                        )?;
1860                    } else {
1861                        unreachable!()
1862                    }
1863                }
1864                3 => {
1865                    #[allow(irrefutable_let_patterns)]
1866                    if let BlockOp::Trim(_) = self {
1867                        // Do nothing, read the value into the object
1868                    } else {
1869                        // Initialize `self` to the right variant
1870                        *self = BlockOp::Trim(fidl::new_empty!(
1871                            BlockTrim,
1872                            fidl::encoding::DefaultFuchsiaResourceDialect
1873                        ));
1874                    }
1875                    #[allow(irrefutable_let_patterns)]
1876                    if let BlockOp::Trim(ref mut val) = self {
1877                        fidl::decode!(
1878                            BlockTrim,
1879                            fidl::encoding::DefaultFuchsiaResourceDialect,
1880                            val,
1881                            decoder,
1882                            _inner_offset,
1883                            depth
1884                        )?;
1885                    } else {
1886                        unreachable!()
1887                    }
1888                }
1889                ordinal => panic!("unexpected ordinal {:?}", ordinal),
1890            }
1891            if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize) {
1892                return Err(fidl::Error::InvalidNumBytesInEnvelope);
1893            }
1894            if handles_before != decoder.remaining_handles() + (num_handles as usize) {
1895                return Err(fidl::Error::InvalidNumHandlesInEnvelope);
1896            }
1897            Ok(())
1898        }
1899    }
1900}