// WARNING: This file is machine generated by fidlgen.

#![allow(
    unused_parens, // one-element-tuple-case is not a tuple
    unused_mut, // not all args require mutation, but many do
    nonstandard_style, // auto-caps does its best, but is not always successful
)]
#![recursion_limit = "512"]

#[cfg(target_os = "fuchsia")]
#[allow(unused_imports)]
use fuchsia_zircon as zx;

#[allow(unused_imports)]
use {
    bitflags::bitflags,
    fidl::{
        client::{decode_transaction_body_fut, QueryResponseFut},
        encoding::{Decodable as _, Encodable as _},
        endpoints::{ControlHandle as _, Responder as _},
        fidl_bits, fidl_empty_struct, fidl_enum, fidl_struct, fidl_struct_copy, fidl_table,
        fidl_union, wrap_handle_metadata,
    },
    fuchsia_zircon_status as zx_status,
    futures::future::{self, MaybeDone, TryFutureExt},
};

const _FIDL_TRACE_BINDINGS_RUST: u32 = 6;
wrap_handle_metadata!(
    HandleWrapperObjectTypeCHANNELRightsCHANNEL_DEFAULT,
    fidl::ObjectType::CHANNEL,
    fidl::Rights::CHANNEL_DEFAULT
);

#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct ChildMarker;

impl fidl::endpoints::ProtocolMarker for ChildMarker {
    type Proxy = ChildProxy;
    type RequestStream = ChildRequestStream;
    const DEBUG_NAME: &'static str = "(anonymous) Child";
}

pub trait ChildProxyInterface: Send + Sync {}

#[derive(Debug)]
#[cfg(target_os = "fuchsia")]
pub struct ChildSynchronousProxy {
    client: fidl::client::sync::Client,
}

#[cfg(target_os = "fuchsia")]
impl ChildSynchronousProxy {
    pub fn new(channel: fidl::Channel) -> Self {
        let protocol_name = <ChildMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
        Self { client: fidl::client::sync::Client::new(channel, protocol_name) }
    }

    pub fn into_channel(self) -> fidl::Channel {
        self.client.into_channel()
    }

    /// Waits until an event arrives and returns it. It is safe for other
    /// threads to make concurrent requests while waiting for an event.
    pub fn wait_for_event(&self, deadline: zx::Time) -> Result<ChildEvent, fidl::Error> {
        ChildEvent::decode(self.client.wait_for_event(deadline)?)
    }
}

#[derive(Debug, Clone)]
pub struct ChildProxy {
    client: fidl::client::Client,
}

impl fidl::endpoints::Proxy for ChildProxy {
    type Protocol = ChildMarker;

    fn from_channel(inner: fidl::AsyncChannel) -> Self {
        Self::new(inner)
    }

    fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
        self.client.into_channel().map_err(|client| Self { client })
    }

    fn as_channel(&self) -> &::fidl::AsyncChannel {
        self.client.as_channel()
    }
}

impl ChildProxy {
    /// Create a new Proxy for Child
    pub fn new(channel: fidl::AsyncChannel) -> Self {
        let protocol_name = <ChildMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
        Self { client: fidl::client::Client::new(channel, protocol_name) }
    }

    /// Get a Stream of events from the remote end of the Child protocol
    ///
    /// # Panics
    ///
    /// Panics if the event stream was already taken.
    pub fn take_event_stream(&self) -> ChildEventStream {
        ChildEventStream { event_receiver: self.client.take_event_receiver() }
    }
}

impl ChildProxyInterface for ChildProxy {}

pub struct ChildEventStream {
    event_receiver: fidl::client::EventReceiver,
}

impl std::marker::Unpin for ChildEventStream {}

impl futures::stream::FusedStream for ChildEventStream {
    fn is_terminated(&self) -> bool {
        self.event_receiver.is_terminated()
    }
}

impl futures::Stream for ChildEventStream {
    type Item = Result<ChildEvent, fidl::Error>;

    fn poll_next(
        mut self: std::pin::Pin<&mut Self>,
        cx: &mut std::task::Context<'_>,
    ) -> std::task::Poll<Option<Self::Item>> {
        let buf = match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
            &mut self.event_receiver,
            cx
        )?) {
            Some(buf) => buf,
            None => return std::task::Poll::Ready(None),
        };

        std::task::Poll::Ready(Some(ChildEvent::decode(buf)))
    }
}

#[derive(Debug)]
pub enum ChildEvent {}

impl ChildEvent {
    fn decode(mut buf: fidl::MessageBufEtc) -> Result<ChildEvent, fidl::Error> {
        let (bytes, _handles) = buf.split_mut();
        let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;

        match tx_header.ordinal() {
            _ => Err(fidl::Error::UnknownOrdinal {
                ordinal: tx_header.ordinal(),
                protocol_name: <ChildMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
            }),
        }
    }
}

/// A Stream of incoming requests for Child
pub struct ChildRequestStream {
    inner: std::sync::Arc<fidl::ServeInner>,
    is_terminated: bool,
}

impl std::marker::Unpin for ChildRequestStream {}

impl futures::stream::FusedStream for ChildRequestStream {
    fn is_terminated(&self) -> bool {
        self.is_terminated
    }
}

impl fidl::endpoints::RequestStream for ChildRequestStream {
    type Protocol = ChildMarker;
    type ControlHandle = ChildControlHandle;

    fn from_channel(channel: fidl::AsyncChannel) -> Self {
        Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
    }

    fn control_handle(&self) -> Self::ControlHandle {
        ChildControlHandle { inner: self.inner.clone() }
    }

    fn into_inner(self) -> (::std::sync::Arc<fidl::ServeInner>, bool) {
        (self.inner, self.is_terminated)
    }

    fn from_inner(inner: std::sync::Arc<fidl::ServeInner>, is_terminated: bool) -> Self {
        Self { inner, is_terminated }
    }
}

impl futures::Stream for ChildRequestStream {
    type Item = Result<ChildRequest, fidl::Error>;

    fn poll_next(
        mut self: std::pin::Pin<&mut Self>,
        cx: &mut std::task::Context<'_>,
    ) -> std::task::Poll<Option<Self::Item>> {
        let this = &mut *self;
        if this.inner.poll_shutdown(cx) {
            this.is_terminated = true;
            return std::task::Poll::Ready(None);
        }
        if this.is_terminated {
            panic!("polled ChildRequestStream after completion");
        }
        fidl::encoding::with_tls_decode_buf(|bytes, handles| {
            match this.inner.channel().read_etc(cx, bytes, handles) {
                std::task::Poll::Ready(Ok(())) => {}
                std::task::Poll::Pending => return std::task::Poll::Pending,
                std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
                    this.is_terminated = true;
                    return std::task::Poll::Ready(None);
                }
                std::task::Poll::Ready(Err(e)) => {
                    return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(e))))
                }
            }

            // A message has been received from the channel
            let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
            if !header.is_compatible() {
                return std::task::Poll::Ready(Some(Err(fidl::Error::IncompatibleMagicNumber(
                    header.magic_number(),
                ))));
            }

            std::task::Poll::Ready(Some(match header.ordinal() {
                _ => Err(fidl::Error::UnknownOrdinal {
                    ordinal: header.ordinal(),
                    protocol_name: <ChildMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
                }),
            }))
        })
    }
}
#[derive(Debug)]
pub enum ChildRequest {}

impl ChildRequest {
    /// Name of the method defined in FIDL
    pub fn method_name(&self) -> &'static str {
        match *self {}
    }
}

#[derive(Debug, Clone)]
pub struct ChildControlHandle {
    inner: std::sync::Arc<fidl::ServeInner>,
}

impl fidl::endpoints::ControlHandle for ChildControlHandle {
    fn shutdown(&self) {
        self.inner.shutdown()
    }

    fn shutdown_with_epitaph(&self, status: zx_status::Status) {
        self.inner.shutdown_with_epitaph(status)
    }
}

impl ChildControlHandle {}

#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct ParentMarker;

impl fidl::endpoints::ProtocolMarker for ParentMarker {
    type Proxy = ParentProxy;
    type RequestStream = ParentRequestStream;
    const DEBUG_NAME: &'static str = "(anonymous) Parent";
}

pub trait ParentProxyInterface: Send + Sync {
    type GetChildResponseFut: std::future::Future<Output = Result<(fidl::endpoints::ClientEnd<ChildMarker>), fidl::Error>>
        + Send;
    fn r#get_child(&self) -> Self::GetChildResponseFut;
    type GetChildRequestResponseFut: std::future::Future<Output = Result<(fidl::endpoints::ServerEnd<ChildMarker>), fidl::Error>>
        + Send;
    fn r#get_child_request(&self) -> Self::GetChildRequestResponseFut;
    fn r#take_child(&self, c: fidl::endpoints::ClientEnd<ChildMarker>) -> Result<(), fidl::Error>;
    fn r#take_child_request(
        &self,
        r: fidl::endpoints::ServerEnd<ChildMarker>,
    ) -> Result<(), fidl::Error>;
}

#[derive(Debug)]
#[cfg(target_os = "fuchsia")]
pub struct ParentSynchronousProxy {
    client: fidl::client::sync::Client,
}

#[cfg(target_os = "fuchsia")]
impl ParentSynchronousProxy {
    pub fn new(channel: fidl::Channel) -> Self {
        let protocol_name = <ParentMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
        Self { client: fidl::client::sync::Client::new(channel, protocol_name) }
    }

    pub fn into_channel(self) -> fidl::Channel {
        self.client.into_channel()
    }

    /// Waits until an event arrives and returns it. It is safe for other
    /// threads to make concurrent requests while waiting for an event.
    pub fn wait_for_event(&self, deadline: zx::Time) -> Result<ParentEvent, fidl::Error> {
        ParentEvent::decode(self.client.wait_for_event(deadline)?)
    }
    pub fn r#get_child(
        &self,
        ___deadline: zx::Time,
    ) -> Result<(fidl::endpoints::ClientEnd<ChildMarker>), fidl::Error> {
        let _value: (
            HandleWrapperObjectTypeCHANNELRightsCHANNEL_DEFAULT<
                fidl::endpoints::ClientEnd<ChildMarker>,
            >,
        ) = self.client.send_query(
            &mut (),
            0xc3cd963aafc873b,
            fidl::encoding::DynamicFlags::empty(),
            ___deadline,
        )?;
        Ok(_value.0.into_inner())
    }
    pub fn r#get_child_request(
        &self,
        ___deadline: zx::Time,
    ) -> Result<(fidl::endpoints::ServerEnd<ChildMarker>), fidl::Error> {
        let _value: (
            HandleWrapperObjectTypeCHANNELRightsCHANNEL_DEFAULT<
                fidl::endpoints::ServerEnd<ChildMarker>,
            >,
        ) = self.client.send_query(
            &mut (),
            0xf38d08d64f71c79,
            fidl::encoding::DynamicFlags::empty(),
            ___deadline,
        )?;
        Ok(_value.0.into_inner())
    }
    pub fn r#take_child(
        &self,
        mut c: fidl::endpoints::ClientEnd<ChildMarker>,
    ) -> Result<(), fidl::Error> {
        self.client.send(
            &mut (HandleWrapperObjectTypeCHANNELRightsCHANNEL_DEFAULT::<
                fidl::endpoints::ClientEnd<ChildMarker>,
            >(c),),
            0x3e08fd7ca04b2290,
            fidl::encoding::DynamicFlags::empty(),
        )
    }
    pub fn r#take_child_request(
        &self,
        mut r: fidl::endpoints::ServerEnd<ChildMarker>,
    ) -> Result<(), fidl::Error> {
        self.client.send(
            &mut (HandleWrapperObjectTypeCHANNELRightsCHANNEL_DEFAULT::<
                fidl::endpoints::ServerEnd<ChildMarker>,
            >(r),),
            0x2063f76b1bb45f87,
            fidl::encoding::DynamicFlags::empty(),
        )
    }
}

#[derive(Debug, Clone)]
pub struct ParentProxy {
    client: fidl::client::Client,
}

impl fidl::endpoints::Proxy for ParentProxy {
    type Protocol = ParentMarker;

    fn from_channel(inner: fidl::AsyncChannel) -> Self {
        Self::new(inner)
    }

    fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
        self.client.into_channel().map_err(|client| Self { client })
    }

    fn as_channel(&self) -> &::fidl::AsyncChannel {
        self.client.as_channel()
    }
}

impl ParentProxy {
    /// Create a new Proxy for Parent
    pub fn new(channel: fidl::AsyncChannel) -> Self {
        let protocol_name = <ParentMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
        Self { client: fidl::client::Client::new(channel, protocol_name) }
    }

    /// Get a Stream of events from the remote end of the Parent protocol
    ///
    /// # Panics
    ///
    /// Panics if the event stream was already taken.
    pub fn take_event_stream(&self) -> ParentEventStream {
        ParentEventStream { event_receiver: self.client.take_event_receiver() }
    }
    pub fn r#get_child(
        &self,
    ) -> fidl::client::QueryResponseFut<(fidl::endpoints::ClientEnd<ChildMarker>)> {
        ParentProxyInterface::r#get_child(self)
    }
    pub fn r#get_child_request(
        &self,
    ) -> fidl::client::QueryResponseFut<(fidl::endpoints::ServerEnd<ChildMarker>)> {
        ParentProxyInterface::r#get_child_request(self)
    }
    pub fn r#take_child(
        &self,
        mut c: fidl::endpoints::ClientEnd<ChildMarker>,
    ) -> Result<(), fidl::Error> {
        ParentProxyInterface::r#take_child(self, c)
    }
    pub fn r#take_child_request(
        &self,
        mut r: fidl::endpoints::ServerEnd<ChildMarker>,
    ) -> Result<(), fidl::Error> {
        ParentProxyInterface::r#take_child_request(self, r)
    }
}

impl ParentProxyInterface for ParentProxy {
    type GetChildResponseFut =
        fidl::client::QueryResponseFut<(fidl::endpoints::ClientEnd<ChildMarker>)>;
    fn r#get_child(&self) -> Self::GetChildResponseFut {
        fn transform(
            result: Result<
                (
                    HandleWrapperObjectTypeCHANNELRightsCHANNEL_DEFAULT<
                        fidl::endpoints::ClientEnd<ChildMarker>,
                    >,
                ),
                fidl::Error,
            >,
        ) -> Result<(fidl::endpoints::ClientEnd<ChildMarker>), fidl::Error> {
            result.map(|_value| _value.0.into_inner())
        }
        let send_result = self.client.call_send_raw_query(
            &mut (),
            0xc3cd963aafc873b,
            fidl::encoding::DynamicFlags::empty(),
        );
        QueryResponseFut(match send_result {
            Ok(res_fut) => future::maybe_done(
                res_fut.and_then(|buf| decode_transaction_body_fut(buf, transform)),
            ),
            Err(e) => MaybeDone::Done(Err(e)),
        })
    }
    type GetChildRequestResponseFut =
        fidl::client::QueryResponseFut<(fidl::endpoints::ServerEnd<ChildMarker>)>;
    fn r#get_child_request(&self) -> Self::GetChildRequestResponseFut {
        fn transform(
            result: Result<
                (
                    HandleWrapperObjectTypeCHANNELRightsCHANNEL_DEFAULT<
                        fidl::endpoints::ServerEnd<ChildMarker>,
                    >,
                ),
                fidl::Error,
            >,
        ) -> Result<(fidl::endpoints::ServerEnd<ChildMarker>), fidl::Error> {
            result.map(|_value| _value.0.into_inner())
        }
        let send_result = self.client.call_send_raw_query(
            &mut (),
            0xf38d08d64f71c79,
            fidl::encoding::DynamicFlags::empty(),
        );
        QueryResponseFut(match send_result {
            Ok(res_fut) => future::maybe_done(
                res_fut.and_then(|buf| decode_transaction_body_fut(buf, transform)),
            ),
            Err(e) => MaybeDone::Done(Err(e)),
        })
    }
    fn r#take_child(
        &self,
        mut c: fidl::endpoints::ClientEnd<ChildMarker>,
    ) -> Result<(), fidl::Error> {
        self.client.send(
            &mut (HandleWrapperObjectTypeCHANNELRightsCHANNEL_DEFAULT::<
                fidl::endpoints::ClientEnd<ChildMarker>,
            >(c)),
            0x3e08fd7ca04b2290,
            fidl::encoding::DynamicFlags::empty(),
        )
    }
    fn r#take_child_request(
        &self,
        mut r: fidl::endpoints::ServerEnd<ChildMarker>,
    ) -> Result<(), fidl::Error> {
        self.client.send(
            &mut (HandleWrapperObjectTypeCHANNELRightsCHANNEL_DEFAULT::<
                fidl::endpoints::ServerEnd<ChildMarker>,
            >(r)),
            0x2063f76b1bb45f87,
            fidl::encoding::DynamicFlags::empty(),
        )
    }
}

pub struct ParentEventStream {
    event_receiver: fidl::client::EventReceiver,
}

impl std::marker::Unpin for ParentEventStream {}

impl futures::stream::FusedStream for ParentEventStream {
    fn is_terminated(&self) -> bool {
        self.event_receiver.is_terminated()
    }
}

impl futures::Stream for ParentEventStream {
    type Item = Result<ParentEvent, fidl::Error>;

    fn poll_next(
        mut self: std::pin::Pin<&mut Self>,
        cx: &mut std::task::Context<'_>,
    ) -> std::task::Poll<Option<Self::Item>> {
        let buf = match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
            &mut self.event_receiver,
            cx
        )?) {
            Some(buf) => buf,
            None => return std::task::Poll::Ready(None),
        };

        std::task::Poll::Ready(Some(ParentEvent::decode(buf)))
    }
}

#[derive(Debug)]
pub enum ParentEvent {}

impl ParentEvent {
    fn decode(mut buf: fidl::MessageBufEtc) -> Result<ParentEvent, fidl::Error> {
        let (bytes, _handles) = buf.split_mut();
        let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;

        match tx_header.ordinal() {
            _ => Err(fidl::Error::UnknownOrdinal {
                ordinal: tx_header.ordinal(),
                protocol_name: <ParentMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
            }),
        }
    }
}

/// A Stream of incoming requests for Parent
pub struct ParentRequestStream {
    inner: std::sync::Arc<fidl::ServeInner>,
    is_terminated: bool,
}

impl std::marker::Unpin for ParentRequestStream {}

impl futures::stream::FusedStream for ParentRequestStream {
    fn is_terminated(&self) -> bool {
        self.is_terminated
    }
}

impl fidl::endpoints::RequestStream for ParentRequestStream {
    type Protocol = ParentMarker;
    type ControlHandle = ParentControlHandle;

    fn from_channel(channel: fidl::AsyncChannel) -> Self {
        Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
    }

    fn control_handle(&self) -> Self::ControlHandle {
        ParentControlHandle { inner: self.inner.clone() }
    }

    fn into_inner(self) -> (::std::sync::Arc<fidl::ServeInner>, bool) {
        (self.inner, self.is_terminated)
    }

    fn from_inner(inner: std::sync::Arc<fidl::ServeInner>, is_terminated: bool) -> Self {
        Self { inner, is_terminated }
    }
}

impl futures::Stream for ParentRequestStream {
    type Item = Result<ParentRequest, fidl::Error>;

    fn poll_next(
        mut self: std::pin::Pin<&mut Self>,
        cx: &mut std::task::Context<'_>,
    ) -> std::task::Poll<Option<Self::Item>> {
        let this = &mut *self;
        if this.inner.poll_shutdown(cx) {
            this.is_terminated = true;
            return std::task::Poll::Ready(None);
        }
        if this.is_terminated {
            panic!("polled ParentRequestStream after completion");
        }
        fidl::encoding::with_tls_decode_buf(|bytes, handles| {
            match this.inner.channel().read_etc(cx, bytes, handles) {
                std::task::Poll::Ready(Ok(())) => {}
                std::task::Poll::Pending => return std::task::Poll::Pending,
                std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
                    this.is_terminated = true;
                    return std::task::Poll::Ready(None);
                }
                std::task::Poll::Ready(Err(e)) => {
                    return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(e))))
                }
            }

            // A message has been received from the channel
            let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
            if !header.is_compatible() {
                return std::task::Poll::Ready(Some(Err(fidl::Error::IncompatibleMagicNumber(
                    header.magic_number(),
                ))));
            }

            std::task::Poll::Ready(Some(match header.ordinal() {
                0xc3cd963aafc873b => {
                    let mut req: () = fidl::encoding::Decodable::new_empty();
                    fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolrequest/ParentGetChildRequest");
                    fidl::trace_blob!("fidl:blob", "decode", bytes);
                    fidl::encoding::Decoder::decode_into(&header, _body_bytes, handles, &mut req)?;
                    fidl::duration_end!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => handles.len() as u32);
                    let control_handle = ParentControlHandle { inner: this.inner.clone() };

                    Ok(ParentRequest::GetChild {
                        responder: ParentGetChildResponder {
                            control_handle: std::mem::ManuallyDrop::new(control_handle),
                            tx_id: header.tx_id(),
                            ordinal: header.ordinal(),
                        },
                    })
                }
                0xf38d08d64f71c79 => {
                    let mut req: () = fidl::encoding::Decodable::new_empty();
                    fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolrequest/ParentGetChildRequestRequest");
                    fidl::trace_blob!("fidl:blob", "decode", bytes);
                    fidl::encoding::Decoder::decode_into(&header, _body_bytes, handles, &mut req)?;
                    fidl::duration_end!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => handles.len() as u32);
                    let control_handle = ParentControlHandle { inner: this.inner.clone() };

                    Ok(ParentRequest::GetChildRequest {
                        responder: ParentGetChildRequestResponder {
                            control_handle: std::mem::ManuallyDrop::new(control_handle),
                            tx_id: header.tx_id(),
                            ordinal: header.ordinal(),
                        },
                    })
                }
                0x3e08fd7ca04b2290 => {
                    let mut req: (
                        HandleWrapperObjectTypeCHANNELRightsCHANNEL_DEFAULT<
                            fidl::endpoints::ClientEnd<ChildMarker>,
                        >,
                    ) = fidl::encoding::Decodable::new_empty();
                    fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolrequest/ParentTakeChildRequest");
                    fidl::trace_blob!("fidl:blob", "decode", bytes);
                    fidl::encoding::Decoder::decode_into(&header, _body_bytes, handles, &mut req)?;
                    fidl::duration_end!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => handles.len() as u32);
                    let control_handle = ParentControlHandle { inner: this.inner.clone() };

                    Ok(ParentRequest::TakeChild { c: req.0.into_inner(), control_handle })
                }
                0x2063f76b1bb45f87 => {
                    let mut req: (
                        HandleWrapperObjectTypeCHANNELRightsCHANNEL_DEFAULT<
                            fidl::endpoints::ServerEnd<ChildMarker>,
                        >,
                    ) = fidl::encoding::Decodable::new_empty();
                    fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolrequest/ParentTakeChildRequestRequest");
                    fidl::trace_blob!("fidl:blob", "decode", bytes);
                    fidl::encoding::Decoder::decode_into(&header, _body_bytes, handles, &mut req)?;
                    fidl::duration_end!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => handles.len() as u32);
                    let control_handle = ParentControlHandle { inner: this.inner.clone() };

                    Ok(ParentRequest::TakeChildRequest { r: req.0.into_inner(), control_handle })
                }
                _ => Err(fidl::Error::UnknownOrdinal {
                    ordinal: header.ordinal(),
                    protocol_name: <ParentMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
                }),
            }))
        })
    }
}
#[derive(Debug)]
pub enum ParentRequest {
    GetChild {
        responder: ParentGetChildResponder,
    },
    GetChildRequest {
        responder: ParentGetChildRequestResponder,
    },
    TakeChild {
        c: fidl::endpoints::ClientEnd<ChildMarker>,
        control_handle: ParentControlHandle,
    },
    TakeChildRequest {
        r: fidl::endpoints::ServerEnd<ChildMarker>,
        control_handle: ParentControlHandle,
    },
}

impl ParentRequest {
    #[allow(irrefutable_let_patterns)]
    pub fn into_get_child(self) -> Option<(ParentGetChildResponder)> {
        if let ParentRequest::GetChild { responder } = self {
            Some((responder))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_get_child_request(self) -> Option<(ParentGetChildRequestResponder)> {
        if let ParentRequest::GetChildRequest { responder } = self {
            Some((responder))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_take_child(
        self,
    ) -> Option<(fidl::endpoints::ClientEnd<ChildMarker>, ParentControlHandle)> {
        if let ParentRequest::TakeChild { c, control_handle } = self {
            Some((c, control_handle))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_take_child_request(
        self,
    ) -> Option<(fidl::endpoints::ServerEnd<ChildMarker>, ParentControlHandle)> {
        if let ParentRequest::TakeChildRequest { r, control_handle } = self {
            Some((r, control_handle))
        } else {
            None
        }
    }

    /// Name of the method defined in FIDL
    pub fn method_name(&self) -> &'static str {
        match *self {
            ParentRequest::GetChild { .. } => "get_child",
            ParentRequest::GetChildRequest { .. } => "get_child_request",
            ParentRequest::TakeChild { .. } => "take_child",
            ParentRequest::TakeChildRequest { .. } => "take_child_request",
        }
    }
}

#[derive(Debug, Clone)]
pub struct ParentControlHandle {
    inner: std::sync::Arc<fidl::ServeInner>,
}

impl fidl::endpoints::ControlHandle for ParentControlHandle {
    fn shutdown(&self) {
        self.inner.shutdown()
    }

    fn shutdown_with_epitaph(&self, status: zx_status::Status) {
        self.inner.shutdown_with_epitaph(status)
    }
}

impl ParentControlHandle {}
#[must_use = "FIDL methods require a response to be sent"]
#[derive(Debug)]
pub struct ParentGetChildResponder {
    control_handle: std::mem::ManuallyDrop<ParentControlHandle>,
    tx_id: u32,
    ordinal: u64,
}

/// Set the the channel to be shutdown (see [`ParentControlHandle::shutdown`])
/// if the responder is dropped without sending a response, so that the client
/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
impl std::ops::Drop for ParentGetChildResponder {
    fn drop(&mut self) {
        self.control_handle.shutdown();
        // Safety: drops once, never accessed again
        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
    }
}

impl fidl::endpoints::Responder for ParentGetChildResponder {
    type ControlHandle = ParentControlHandle;

    fn control_handle(&self) -> &ParentControlHandle {
        &self.control_handle
    }

    fn drop_without_shutdown(mut self) {
        // Safety: drops once, never accessed again due to mem::forget
        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
        // Prevent Drop from running (which would shut down the channel)
        std::mem::forget(self);
    }
}

impl ParentGetChildResponder {
    /// Sends a response to the FIDL transaction.
    ///
    /// Sets the channel to shutdown if an error occurs.
    pub fn send(self, mut c: fidl::endpoints::ClientEnd<ChildMarker>) -> Result<(), fidl::Error> {
        let r = self.send_raw(c);
        if r.is_err() {
            self.control_handle.shutdown();
        }
        self.drop_without_shutdown();
        r
    }

    /// Similar to "send" but does not shutdown the channel if
    /// an error occurs.
    pub fn send_no_shutdown_on_err(
        self,
        mut c: fidl::endpoints::ClientEnd<ChildMarker>,
    ) -> Result<(), fidl::Error> {
        let r = self.send_raw(c);
        self.drop_without_shutdown();
        r
    }

    fn send_raw(&self, mut c: fidl::endpoints::ClientEnd<ChildMarker>) -> Result<(), fidl::Error> {
        let mut response = (HandleWrapperObjectTypeCHANNELRightsCHANNEL_DEFAULT::<
            fidl::endpoints::ClientEnd<ChildMarker>,
        >(c));

        let mut msg = fidl::encoding::TransactionMessage {
            header: fidl::encoding::TransactionHeader::new(
                self.tx_id,
                self.ordinal,
                fidl::encoding::DynamicFlags::empty(),
            ),
            body: &mut response,
        };

        fidl::encoding::with_tls_encode_buf(|bytes, handles| {
            fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolrequest/ParentGetChildResponse");
            fidl::encoding::Encoder::encode(bytes, handles, &mut msg)?;
            fidl::trace_blob!("fidl:blob", "encode", bytes.as_slice());
            fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => handles.len() as u32);

            self.control_handle
                .inner
                .channel()
                .write_etc(&*bytes, &mut *handles)
                .map_err(fidl::Error::ServerResponseWrite)?;
            Ok(())
        })
    }
}
#[must_use = "FIDL methods require a response to be sent"]
#[derive(Debug)]
pub struct ParentGetChildRequestResponder {
    control_handle: std::mem::ManuallyDrop<ParentControlHandle>,
    tx_id: u32,
    ordinal: u64,
}

/// Set the the channel to be shutdown (see [`ParentControlHandle::shutdown`])
/// if the responder is dropped without sending a response, so that the client
/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
impl std::ops::Drop for ParentGetChildRequestResponder {
    fn drop(&mut self) {
        self.control_handle.shutdown();
        // Safety: drops once, never accessed again
        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
    }
}

impl fidl::endpoints::Responder for ParentGetChildRequestResponder {
    type ControlHandle = ParentControlHandle;

    fn control_handle(&self) -> &ParentControlHandle {
        &self.control_handle
    }

    fn drop_without_shutdown(mut self) {
        // Safety: drops once, never accessed again due to mem::forget
        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
        // Prevent Drop from running (which would shut down the channel)
        std::mem::forget(self);
    }
}

impl ParentGetChildRequestResponder {
    /// Sends a response to the FIDL transaction.
    ///
    /// Sets the channel to shutdown if an error occurs.
    pub fn send(self, mut r: fidl::endpoints::ServerEnd<ChildMarker>) -> Result<(), fidl::Error> {
        let r = self.send_raw(r);
        if r.is_err() {
            self.control_handle.shutdown();
        }
        self.drop_without_shutdown();
        r
    }

    /// Similar to "send" but does not shutdown the channel if
    /// an error occurs.
    pub fn send_no_shutdown_on_err(
        self,
        mut r: fidl::endpoints::ServerEnd<ChildMarker>,
    ) -> Result<(), fidl::Error> {
        let r = self.send_raw(r);
        self.drop_without_shutdown();
        r
    }

    fn send_raw(&self, mut r: fidl::endpoints::ServerEnd<ChildMarker>) -> Result<(), fidl::Error> {
        let mut response = (HandleWrapperObjectTypeCHANNELRightsCHANNEL_DEFAULT::<
            fidl::endpoints::ServerEnd<ChildMarker>,
        >(r));

        let mut msg = fidl::encoding::TransactionMessage {
            header: fidl::encoding::TransactionHeader::new(
                self.tx_id,
                self.ordinal,
                fidl::encoding::DynamicFlags::empty(),
            ),
            body: &mut response,
        };

        fidl::encoding::with_tls_encode_buf(|bytes, handles| {
            fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolrequest/ParentGetChildRequestResponse");
            fidl::encoding::Encoder::encode(bytes, handles, &mut msg)?;
            fidl::trace_blob!("fidl:blob", "encode", bytes.as_slice());
            fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => handles.len() as u32);

            self.control_handle
                .inner
                .channel()
                .write_etc(&*bytes, &mut *handles)
                .map_err(fidl::Error::ServerResponseWrite)?;
            Ok(())
        })
    }
}
