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

#![allow(
	deprecated, // FIDL Impl struct pattern is referenced internally
	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
)]

#[allow(unused_imports)]
use fidl::{fidl_bits, fidl_empty_struct, fidl_enum, fidl_struct, fidl_table, fidl_xunion};
#[cfg(target_os = "fuchsia")]
#[allow(unused_imports)]
use fuchsia_zircon as zx;
#[allow(unused_imports)]
use fuchsia_zircon_status as zx_status;

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

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

pub trait ParentProxyInterface: Send + Sync {
    fn first(&self, request: fidl::endpoints::ServerEnd<ParentMarker>) -> 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 {
        Self { client: fidl::client::sync::Client::new(channel) }
    }

    pub fn into_channel(self) -> ::fidl::Channel {
        self.client.into_channel()
    }
    pub fn first(
        &mut self,
        mut request: fidl::endpoints::ServerEnd<ParentMarker>,
    ) -> Result<(), fidl::Error> {
        self.client.send(&mut (request), 0x239f8fdea8de880c)
    }
}

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

impl fidl::endpoints::Proxy for ParentProxy {
    type Service = ParentMarker;
    fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
        Self::new(inner)
    }
}

impl ::std::ops::Deref for ParentProxy {
    type Target = fidl::client::Client;

    fn deref(&self) -> &Self::Target {
        &self.client
    }
}

impl ParentProxy {
    /// Create a new Proxy for Parent
    pub fn new(channel: ::fidl::AsyncChannel) -> Self {
        Self { client: fidl::client::Client::new(channel) }
    }

    /// Attempt to convert the Proxy back into a channel.
    ///
    /// This will only succeed if there are no active clones of this Proxy
    /// and no currently-alive EventStream or response futures that came from
    /// this Proxy.
    pub fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
        self.client.into_channel().map_err(|client| Self { client })
    }

    /// Get a Stream of events from the remote end of the Parent protocol
    pub fn take_event_stream(&self) -> ParentEventStream {
        ParentEventStream { event_receiver: self.client.take_event_receiver() }
    }
    pub fn first(
        &self,
        mut request: fidl::endpoints::ServerEnd<ParentMarker>,
    ) -> Result<(), fidl::Error> {
        ParentProxyInterface::first(self, request)
    }
}

impl ParentProxyInterface for ParentProxy {
    fn first(
        &self,
        mut request: fidl::endpoints::ServerEnd<ParentMarker>,
    ) -> Result<(), fidl::Error> {
        self.client.send(&mut (request), 0x239f8fdea8de880c)
    }
}

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 mut 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),
        };
        let (bytes, _handles) = buf.split_mut();
        let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;

        #[allow(unreachable_patterns)] // GenOrdinal and Ordinal can overlap
        std::task::Poll::Ready(Some(match tx_header.ordinal() {
            _ => Err(fidl::Error::UnknownOrdinal {
                ordinal: tx_header.ordinal(),
                service_name: <ParentMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
            }),
        }))
    }
}

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

impl ParentEvent {}

/// A type which can be used to send responses and events into a borrowed channel.
///
/// Note: this should only be used when the channel must be temporarily
/// borrowed. For a typical sending of events, use the send_ methods
/// on the ControlHandle types, which can be acquired through a
/// RequestStream or Responder type.
#[deprecated(note = "Use ParentRequestStream / Responder instead")]
pub struct ParentServerSender<'a> {
    // Some protocols don't define events which would render this channel unused.
    #[allow(unused)]
    channel: &'a ::fidl::Channel,
}

impl<'a> ParentServerSender<'a> {
    pub fn new(channel: &'a ::fidl::Channel) -> Self {
        Self { channel }
    }
}

/// 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 Service = ParentMarker;

    /// Consume a channel to make a ParentRequestStream
    fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
        Self { inner: ::std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
    }

    /// ControlHandle for the remote connection
    type ControlHandle = ParentControlHandle;

    /// ControlHandle for the remote connection
    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_coding_bufs(|bytes, handles| {
            match this.inner.channel().read(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(),
                ))));
            }

            #[allow(unreachable_patterns)] // GenOrdinal and Ordinal can overlap
            std::task::Poll::Ready(Some(match header.ordinal() {
                0x66a95ddc00000000 | 0x239f8fdea8de880c => {
                    let mut req: (fidl::endpoints::ServerEnd<ParentMarker>) =
                        fidl::encoding::Decodable::new_empty();
                    fidl::encoding::Decoder::decode_into(&header, _body_bytes, handles, &mut req)?;
                    let control_handle = ParentControlHandle { inner: this.inner.clone() };

                    Ok(ParentRequest::First { request: req, control_handle })
                }
                _ => Err(fidl::Error::UnknownOrdinal {
                    ordinal: header.ordinal(),
                    service_name: <ParentMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
                }),
            }))
        })
    }
}

/// Represents a single request.
/// RequestMessages should only be used for manual deserialization when higher level
/// structs such as RequestStream cannot be used. One usually would only encounter
/// such scenarios when working with legacy FIDL code (prior to FIDL generated client/server bindings).
#[derive(Debug)]
#[deprecated(note = "Use ParentRequest instead")]
pub enum ParentRequestMessage {
    First { request: fidl::endpoints::ServerEnd<ParentMarker> },
}

impl ParentRequestMessage {
    pub fn decode(
        bytes: &[u8],
        _handles: &mut [fidl::Handle],
    ) -> Result<ParentRequestMessage, fidl::Error> {
        let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;

        #[allow(unreachable_patterns)] // GenOrdinal and Ordinal can overlap
        match header.ordinal() {
            0x66a95ddc00000000 | 0x239f8fdea8de880c => {
                let mut out_tuple: (fidl::endpoints::ServerEnd<ParentMarker>) =
                    fidl::encoding::Decodable::new_empty();
                fidl::encoding::Decoder::decode_into(
                    &header,
                    _body_bytes,
                    _handles,
                    &mut out_tuple,
                )?;

                Ok(ParentRequestMessage::First { request: out_tuple })
            }
            _ => Err(fidl::Error::UnknownOrdinal {
                ordinal: header.ordinal(),
                service_name: <ParentMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
            }),
        }
    }
}
#[derive(Debug)]
pub enum ParentRequest {
    First { request: fidl::endpoints::ServerEnd<ParentMarker>, control_handle: ParentControlHandle },
}

impl ParentRequest {
    #[allow(irrefutable_let_patterns)]
    pub fn into_first(
        self,
    ) -> Option<(fidl::endpoints::ServerEnd<ParentMarker>, ParentControlHandle)> {
        if let ParentRequest::First { request, control_handle } = self {
            Some((request, control_handle))
        } else {
            None
        }
    }

    /// Name of the method defined in FIDL
    pub fn method_name(&self) -> &'static str {
        match *self {
            ParentRequest::First { .. } => "first",
        }
    }
}

pub struct ParentEncoder;

impl ParentEncoder {
    pub fn encode_first_request<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::Handle>,
        mut in_request: fidl::endpoints::ServerEnd<ParentMarker>,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(0, 0x239f8fdea8de880c);
        let mut body = (in_request,);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        Ok(())
    }
}

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

impl ::std::ops::Deref for ParentControlHandle {
    type Target = ::std::sync::Arc<fidl::ServeInner>;

    fn deref(&self) -> &Self::Target {
        &self.inner
    }
}

impl ParentControlHandle {
    pub fn shutdown(&self) {
        self.inner.shutdown()
    }

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

/* beginning of response types */

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

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

pub trait ChildProxyInterface: Send + Sync {
    fn first(&self, request: fidl::endpoints::ServerEnd<ParentMarker>) -> Result<(), fidl::Error>;
    fn second(&self, request: fidl::endpoints::ServerEnd<ParentMarker>) -> Result<(), fidl::Error>;
}

#[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 {
        Self { client: fidl::client::sync::Client::new(channel) }
    }

    pub fn into_channel(self) -> ::fidl::Channel {
        self.client.into_channel()
    }
    pub fn first(
        &mut self,
        mut request: fidl::endpoints::ServerEnd<ParentMarker>,
    ) -> Result<(), fidl::Error> {
        self.client.send(&mut (request), 0x239f8fdea8de880c)
    }
    pub fn second(
        &mut self,
        mut request: fidl::endpoints::ServerEnd<ParentMarker>,
    ) -> Result<(), fidl::Error> {
        self.client.send(&mut (request), 0x24799ea8916d88af)
    }
}

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

impl fidl::endpoints::Proxy for ChildProxy {
    type Service = ChildMarker;
    fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
        Self::new(inner)
    }
}

impl ::std::ops::Deref for ChildProxy {
    type Target = fidl::client::Client;

    fn deref(&self) -> &Self::Target {
        &self.client
    }
}

impl ChildProxy {
    /// Create a new Proxy for Child
    pub fn new(channel: ::fidl::AsyncChannel) -> Self {
        Self { client: fidl::client::Client::new(channel) }
    }

    /// Attempt to convert the Proxy back into a channel.
    ///
    /// This will only succeed if there are no active clones of this Proxy
    /// and no currently-alive EventStream or response futures that came from
    /// this Proxy.
    pub fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
        self.client.into_channel().map_err(|client| Self { client })
    }

    /// Get a Stream of events from the remote end of the Child protocol
    pub fn take_event_stream(&self) -> ChildEventStream {
        ChildEventStream { event_receiver: self.client.take_event_receiver() }
    }
    pub fn first(
        &self,
        mut request: fidl::endpoints::ServerEnd<ParentMarker>,
    ) -> Result<(), fidl::Error> {
        ChildProxyInterface::first(self, request)
    }
    pub fn second(
        &self,
        mut request: fidl::endpoints::ServerEnd<ParentMarker>,
    ) -> Result<(), fidl::Error> {
        ChildProxyInterface::second(self, request)
    }
}

impl ChildProxyInterface for ChildProxy {
    fn first(
        &self,
        mut request: fidl::endpoints::ServerEnd<ParentMarker>,
    ) -> Result<(), fidl::Error> {
        self.client.send(&mut (request), 0x239f8fdea8de880c)
    }
    fn second(
        &self,
        mut request: fidl::endpoints::ServerEnd<ParentMarker>,
    ) -> Result<(), fidl::Error> {
        self.client.send(&mut (request), 0x24799ea8916d88af)
    }
}

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 mut 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),
        };
        let (bytes, _handles) = buf.split_mut();
        let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;

        #[allow(unreachable_patterns)] // GenOrdinal and Ordinal can overlap
        std::task::Poll::Ready(Some(match tx_header.ordinal() {
            _ => Err(fidl::Error::UnknownOrdinal {
                ordinal: tx_header.ordinal(),
                service_name: <ChildMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
            }),
        }))
    }
}

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

impl ChildEvent {}

/// A type which can be used to send responses and events into a borrowed channel.
///
/// Note: this should only be used when the channel must be temporarily
/// borrowed. For a typical sending of events, use the send_ methods
/// on the ControlHandle types, which can be acquired through a
/// RequestStream or Responder type.
#[deprecated(note = "Use ChildRequestStream / Responder instead")]
pub struct ChildServerSender<'a> {
    // Some protocols don't define events which would render this channel unused.
    #[allow(unused)]
    channel: &'a ::fidl::Channel,
}

impl<'a> ChildServerSender<'a> {
    pub fn new(channel: &'a ::fidl::Channel) -> Self {
        Self { channel }
    }
}

/// 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 Service = ChildMarker;

    /// Consume a channel to make a ChildRequestStream
    fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
        Self { inner: ::std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
    }

    /// ControlHandle for the remote connection
    type ControlHandle = ChildControlHandle;

    /// ControlHandle for the remote connection
    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_coding_bufs(|bytes, handles| {
            match this.inner.channel().read(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(),
                ))));
            }

            #[allow(unreachable_patterns)] // GenOrdinal and Ordinal can overlap
            std::task::Poll::Ready(Some(match header.ordinal() {
                0x66a95ddc00000000 | 0x239f8fdea8de880c => {
                    let mut req: (fidl::endpoints::ServerEnd<ParentMarker>) =
                        fidl::encoding::Decodable::new_empty();
                    fidl::encoding::Decoder::decode_into(&header, _body_bytes, handles, &mut req)?;
                    let control_handle = ChildControlHandle { inner: this.inner.clone() };

                    Ok(ChildRequest::First { request: req, control_handle })
                }
                0x1240cb600000000 | 0x24799ea8916d88af => {
                    let mut req: (fidl::endpoints::ServerEnd<ParentMarker>) =
                        fidl::encoding::Decodable::new_empty();
                    fidl::encoding::Decoder::decode_into(&header, _body_bytes, handles, &mut req)?;
                    let control_handle = ChildControlHandle { inner: this.inner.clone() };

                    Ok(ChildRequest::Second { request: req, control_handle })
                }
                _ => Err(fidl::Error::UnknownOrdinal {
                    ordinal: header.ordinal(),
                    service_name: <ChildMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
                }),
            }))
        })
    }
}

/// Represents a single request.
/// RequestMessages should only be used for manual deserialization when higher level
/// structs such as RequestStream cannot be used. One usually would only encounter
/// such scenarios when working with legacy FIDL code (prior to FIDL generated client/server bindings).
#[derive(Debug)]
#[deprecated(note = "Use ChildRequest instead")]
pub enum ChildRequestMessage {
    First { request: fidl::endpoints::ServerEnd<ParentMarker> },
    Second { request: fidl::endpoints::ServerEnd<ParentMarker> },
}

impl ChildRequestMessage {
    pub fn decode(
        bytes: &[u8],
        _handles: &mut [fidl::Handle],
    ) -> Result<ChildRequestMessage, fidl::Error> {
        let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;

        #[allow(unreachable_patterns)] // GenOrdinal and Ordinal can overlap
        match header.ordinal() {
            0x66a95ddc00000000 | 0x239f8fdea8de880c => {
                let mut out_tuple: (fidl::endpoints::ServerEnd<ParentMarker>) =
                    fidl::encoding::Decodable::new_empty();
                fidl::encoding::Decoder::decode_into(
                    &header,
                    _body_bytes,
                    _handles,
                    &mut out_tuple,
                )?;

                Ok(ChildRequestMessage::First { request: out_tuple })
            }
            0x1240cb600000000 | 0x24799ea8916d88af => {
                let mut out_tuple: (fidl::endpoints::ServerEnd<ParentMarker>) =
                    fidl::encoding::Decodable::new_empty();
                fidl::encoding::Decoder::decode_into(
                    &header,
                    _body_bytes,
                    _handles,
                    &mut out_tuple,
                )?;

                Ok(ChildRequestMessage::Second { request: out_tuple })
            }
            _ => Err(fidl::Error::UnknownOrdinal {
                ordinal: header.ordinal(),
                service_name: <ChildMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
            }),
        }
    }
}
#[derive(Debug)]
pub enum ChildRequest {
    First { request: fidl::endpoints::ServerEnd<ParentMarker>, control_handle: ChildControlHandle },
    Second { request: fidl::endpoints::ServerEnd<ParentMarker>, control_handle: ChildControlHandle },
}

impl ChildRequest {
    #[allow(irrefutable_let_patterns)]
    pub fn into_first(
        self,
    ) -> Option<(fidl::endpoints::ServerEnd<ParentMarker>, ChildControlHandle)> {
        if let ChildRequest::First { request, control_handle } = self {
            Some((request, control_handle))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_second(
        self,
    ) -> Option<(fidl::endpoints::ServerEnd<ParentMarker>, ChildControlHandle)> {
        if let ChildRequest::Second { request, control_handle } = self {
            Some((request, control_handle))
        } else {
            None
        }
    }

    /// Name of the method defined in FIDL
    pub fn method_name(&self) -> &'static str {
        match *self {
            ChildRequest::First { .. } => "first",
            ChildRequest::Second { .. } => "second",
        }
    }
}

pub struct ChildEncoder;

impl ChildEncoder {
    pub fn encode_first_request<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::Handle>,
        mut in_request: fidl::endpoints::ServerEnd<ParentMarker>,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(0, 0x239f8fdea8de880c);
        let mut body = (in_request,);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        Ok(())
    }
    pub fn encode_second_request<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::Handle>,
        mut in_request: fidl::endpoints::ServerEnd<ParentMarker>,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(0, 0x24799ea8916d88af);
        let mut body = (in_request,);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        Ok(())
    }
}

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

impl ::std::ops::Deref for ChildControlHandle {
    type Target = ::std::sync::Arc<fidl::ServeInner>;

    fn deref(&self) -> &Self::Target {
        &self.inner
    }
}

impl ChildControlHandle {
    pub fn shutdown(&self) {
        self.inner.shutdown()
    }

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

/* beginning of response types */
