// 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
)]
#![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 _},
        fidl_empty_struct, fidl_flexible_bits, fidl_flexible_enum, fidl_strict_bits,
        fidl_strict_enum, fidl_struct, fidl_struct_copy, fidl_table, fidl_xunion,
        wrap_handle_metadata,
    },
    fuchsia_zircon_status as zx_status,
    futures::future::{self, MaybeDone, TryFutureExt},
};

const _FIDL_TRACE_BINDINGS_RUST: u32 = 6;

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

impl fidl::endpoints::ServiceMarker for Super_Marker {
    type Proxy = Super_Proxy;
    type RequestStream = Super_RequestStream;
    const DEBUG_NAME: &'static str = "(anonymous) Super_";
}

pub trait Super_ProxyInterface: Send + Sync {
    type FooResponseFut: std::future::Future<Output = Result<(i64), fidl::Error>> + Send;
    fn r#foo(&self, s: &str) -> Self::FooResponseFut;
}

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

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

    pub fn into_channel(self) -> fidl::Channel {
        self.client.into_channel()
    }
    pub fn r#foo(&mut self, mut s: &str, ___deadline: zx::Time) -> Result<(i64), fidl::Error> {
        let _value: (i64,) = self.client.send_query(&mut (s), 0x45602cf3b581d6ab, ___deadline)?;
        Ok(_value.0)
    }
}

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

impl fidl::endpoints::Proxy for Super_Proxy {
    type Service = Super_Marker;

    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 Super_Proxy {
    /// Create a new Proxy for Super_
    pub fn new(channel: fidl::AsyncChannel) -> Self {
        let service_name = <Super_Marker as fidl::endpoints::ServiceMarker>::DEBUG_NAME;
        Self { client: fidl::client::Client::new(channel, service_name) }
    }

    /// Get a Stream of events from the remote end of the Super_ protocol
    ///
    /// # Panics
    ///
    /// Panics if the event stream was already taken.
    pub fn take_event_stream(&self) -> Super_EventStream {
        Super_EventStream { event_receiver: self.client.take_event_receiver() }
    }
    pub fn r#foo(&self, mut s: &str) -> fidl::client::QueryResponseFut<(i64)> {
        Super_ProxyInterface::r#foo(self, s)
    }
}

impl Super_ProxyInterface for Super_Proxy {
    type FooResponseFut = fidl::client::QueryResponseFut<(i64)>;
    fn r#foo(&self, mut s: &str) -> Self::FooResponseFut {
        fn transform(result: Result<(i64,), fidl::Error>) -> Result<(i64), fidl::Error> {
            result.map(|_value| _value.0)
        }
        let send_result = self.client.call_send_raw_query(&mut (s), 0x45602cf3b581d6ab);
        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)),
        })
    }
}

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

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

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

impl futures::Stream for Super_EventStream {
    type Item = Result<Super_Event, 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)?;

        std::task::Poll::Ready(Some(match tx_header.ordinal() {
            _ => Err(fidl::Error::UnknownOrdinal {
                ordinal: tx_header.ordinal(),
                service_name: <Super_Marker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
            }),
        }))
    }
}

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

impl Super_Event {}

/// 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 Super_RequestStream / Responder instead")]
pub struct Super_ServerSender<'a> {
    // Some protocols don't define events which would render this channel unused.
    #[allow(unused)]
    channel: &'a fidl::Channel,
}

impl<'a> Super_ServerSender<'a> {
    pub fn new(channel: &'a fidl::Channel) -> Self {
        Self { channel }
    }
    pub fn send_foo_response(
        &self,
        txid: fidl::client::Txid,
        mut y: i64,
    ) -> Result<(), fidl::Error> {
        fidl::encoding::with_tls_encode_buf(|bytes_, handles_| {
            Super_Encoder::encode_foo_response(bytes_, handles_, txid.as_raw_id(), y)?;
            self.channel
                .write_etc(&*bytes_, &mut *handles_)
                .map_err(fidl::Error::ServerResponseWrite)?;
            Ok(())
        })
    }
}

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

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

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

impl fidl::endpoints::RequestStream for Super_RequestStream {
    type Service = Super_Marker;

    /// Consume a channel to make a Super_RequestStream
    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 = Super_ControlHandle;

    /// ControlHandle for the remote connection
    fn control_handle(&self) -> Self::ControlHandle {
        Super_ControlHandle { 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 Super_RequestStream {
    type Item = Result<Super_Request, 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 Super_RequestStream 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() {
                0x45602cf3b581d6ab => {
                    let mut req: (String,) = fidl::encoding::Decodable::new_empty();
                    fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.inheritance/superFooRequest");
                    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 = Super_ControlHandle { inner: this.inner.clone() };

                    Ok(Super_Request::Foo {
                        s: req.0,
                        responder: Super_FooResponder {
                            control_handle: std::mem::ManuallyDrop::new(control_handle),
                            tx_id: header.tx_id(),
                            ordinal: header.ordinal(),
                        },
                    })
                }
                _ => Err(fidl::Error::UnknownOrdinal {
                    ordinal: header.ordinal(),
                    service_name: <Super_Marker 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 Super_Request instead")]
pub enum Super_RequestMessage {
    Foo { s: String, tx_id: fidl::client::Txid },
}

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

        match header.ordinal() {
            0x45602cf3b581d6ab => {
                let mut out_tuple: (String,) = fidl::encoding::Decodable::new_empty();
                fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.inheritance/superFooRequest");
                fidl::trace_blob!("fidl:blob", "decode", bytes);
                fidl::encoding::Decoder::decode_into(
                    &header,
                    _body_bytes,
                    _handles,
                    &mut out_tuple,
                )?;
                fidl::duration_end!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => _handles.len() as u32);

                Ok(Super_RequestMessage::Foo { s: out_tuple.0, tx_id: header.tx_id().into() })
            }
            _ => Err(fidl::Error::UnknownOrdinal {
                ordinal: header.ordinal(),
                service_name: <Super_Marker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
            }),
        }
    }
}
#[derive(Debug)]
pub enum Super_Request {
    Foo { s: String, responder: Super_FooResponder },
}

impl Super_Request {
    #[allow(irrefutable_let_patterns)]
    pub fn into_foo(self) -> Option<(String, Super_FooResponder)> {
        if let Super_Request::Foo { s, responder } = self {
            Some((s, responder))
        } else {
            None
        }
    }

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

pub struct Super_Encoder;

impl Super_Encoder {
    pub fn encode_foo_request<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
        mut in_s: &str,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x45602cf3b581d6ab);
        let mut body = (in_s,);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };
        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.inheritance/superFooRequest");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);
        Ok(())
    }
    pub fn encode_foo_response<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
        mut in_y: i64,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x45602cf3b581d6ab);
        let mut body = (in_y,);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };

        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.inheritance/superFooResponse");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);

        Ok(())
    }
}

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

impl Super_ControlHandle {
    /// Set the server to shutdown. The underlying channel is only closed the
    /// next time the stream is polled.
    pub fn shutdown(&self) {
        self.inner.shutdown()
    }

    pub fn shutdown_with_epitaph(&self, status: zx_status::Status) {
        self.inner.shutdown_with_epitaph(status)
    }
}
#[must_use = "FIDL methods require a response to be sent"]
#[derive(Debug)]
pub struct Super_FooResponder {
    control_handle: std::mem::ManuallyDrop<Super_ControlHandle>,
    tx_id: u32,
    ordinal: u64,
}

/// Set the the channel to be shutdown (see [`Super_ControlHandle::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 Super_FooResponder {
    fn drop(&mut self) {
        self.control_handle.shutdown();
        // Safety: drops once, never accessed again
        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
    }
}

impl Super_FooResponder {
    pub fn control_handle(&self) -> &Super_ControlHandle {
        &self.control_handle
    }

    /// Drop the Responder without setting the channel to shutdown.
    ///
    /// This method shouldn't normally be used-- instead, send a response
    /// to prevent the channel from shutting down.
    pub 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);
    }

    /// Sends a response to the FIDL transaction.
    ///
    /// Sets the channel to shutdown if an error occurs.
    pub fn send(self, mut y: i64) -> Result<(), fidl::Error> {
        let r = self.send_raw(y);
        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 y: i64) -> Result<(), fidl::Error> {
        let r = self.send_raw(y);
        self.drop_without_shutdown();
        r
    }

    fn send_raw(&self, mut y: i64) -> Result<(), fidl::Error> {
        let mut response = (y);

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

        fidl::encoding::with_tls_encode_buf(|bytes, handles| {
            fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.inheritance/superFooResponse");
            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(())
        })
    }
}

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

impl fidl::endpoints::ServiceMarker for SubMarker {
    type Proxy = SubProxy;
    type RequestStream = SubRequestStream;
    const DEBUG_NAME: &'static str = "(anonymous) Sub";
}

pub trait SubProxyInterface: Send + Sync {
    type FooResponseFut: std::future::Future<Output = Result<(i64), fidl::Error>> + Send;
    fn r#foo(&self, s: &str) -> Self::FooResponseFut;
}

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

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

    pub fn into_channel(self) -> fidl::Channel {
        self.client.into_channel()
    }
    pub fn r#foo(&mut self, mut s: &str, ___deadline: zx::Time) -> Result<(i64), fidl::Error> {
        let _value: (i64,) = self.client.send_query(&mut (s), 0x45602cf3b581d6ab, ___deadline)?;
        Ok(_value.0)
    }
}

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

impl fidl::endpoints::Proxy for SubProxy {
    type Service = SubMarker;

    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 SubProxy {
    /// Create a new Proxy for Sub
    pub fn new(channel: fidl::AsyncChannel) -> Self {
        let service_name = <SubMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME;
        Self { client: fidl::client::Client::new(channel, service_name) }
    }

    /// Get a Stream of events from the remote end of the Sub protocol
    ///
    /// # Panics
    ///
    /// Panics if the event stream was already taken.
    pub fn take_event_stream(&self) -> SubEventStream {
        SubEventStream { event_receiver: self.client.take_event_receiver() }
    }
    pub fn r#foo(&self, mut s: &str) -> fidl::client::QueryResponseFut<(i64)> {
        SubProxyInterface::r#foo(self, s)
    }
}

impl SubProxyInterface for SubProxy {
    type FooResponseFut = fidl::client::QueryResponseFut<(i64)>;
    fn r#foo(&self, mut s: &str) -> Self::FooResponseFut {
        fn transform(result: Result<(i64,), fidl::Error>) -> Result<(i64), fidl::Error> {
            result.map(|_value| _value.0)
        }
        let send_result = self.client.call_send_raw_query(&mut (s), 0x45602cf3b581d6ab);
        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)),
        })
    }
}

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

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

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

impl futures::Stream for SubEventStream {
    type Item = Result<SubEvent, 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)?;

        std::task::Poll::Ready(Some(match tx_header.ordinal() {
            _ => Err(fidl::Error::UnknownOrdinal {
                ordinal: tx_header.ordinal(),
                service_name: <SubMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
            }),
        }))
    }
}

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

impl SubEvent {}

/// 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 SubRequestStream / Responder instead")]
pub struct SubServerSender<'a> {
    // Some protocols don't define events which would render this channel unused.
    #[allow(unused)]
    channel: &'a fidl::Channel,
}

impl<'a> SubServerSender<'a> {
    pub fn new(channel: &'a fidl::Channel) -> Self {
        Self { channel }
    }
    pub fn send_foo_response(
        &self,
        txid: fidl::client::Txid,
        mut y: i64,
    ) -> Result<(), fidl::Error> {
        fidl::encoding::with_tls_encode_buf(|bytes_, handles_| {
            SubEncoder::encode_foo_response(bytes_, handles_, txid.as_raw_id(), y)?;
            self.channel
                .write_etc(&*bytes_, &mut *handles_)
                .map_err(fidl::Error::ServerResponseWrite)?;
            Ok(())
        })
    }
}

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

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

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

impl fidl::endpoints::RequestStream for SubRequestStream {
    type Service = SubMarker;

    /// Consume a channel to make a SubRequestStream
    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 = SubControlHandle;

    /// ControlHandle for the remote connection
    fn control_handle(&self) -> Self::ControlHandle {
        SubControlHandle { 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 SubRequestStream {
    type Item = Result<SubRequest, 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 SubRequestStream 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() {
                0x45602cf3b581d6ab => {
                    let mut req: (String,) = fidl::encoding::Decodable::new_empty();
                    fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.inheritance/subFooRequest");
                    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 = SubControlHandle { inner: this.inner.clone() };

                    Ok(SubRequest::Foo {
                        s: req.0,
                        responder: SubFooResponder {
                            control_handle: std::mem::ManuallyDrop::new(control_handle),
                            tx_id: header.tx_id(),
                            ordinal: header.ordinal(),
                        },
                    })
                }
                _ => Err(fidl::Error::UnknownOrdinal {
                    ordinal: header.ordinal(),
                    service_name: <SubMarker 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 SubRequest instead")]
pub enum SubRequestMessage {
    Foo { s: String, tx_id: fidl::client::Txid },
}

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

        match header.ordinal() {
            0x45602cf3b581d6ab => {
                let mut out_tuple: (String,) = fidl::encoding::Decodable::new_empty();
                fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.inheritance/subFooRequest");
                fidl::trace_blob!("fidl:blob", "decode", bytes);
                fidl::encoding::Decoder::decode_into(
                    &header,
                    _body_bytes,
                    _handles,
                    &mut out_tuple,
                )?;
                fidl::duration_end!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => _handles.len() as u32);

                Ok(SubRequestMessage::Foo { s: out_tuple.0, tx_id: header.tx_id().into() })
            }
            _ => Err(fidl::Error::UnknownOrdinal {
                ordinal: header.ordinal(),
                service_name: <SubMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
            }),
        }
    }
}
#[derive(Debug)]
pub enum SubRequest {
    Foo { s: String, responder: SubFooResponder },
}

impl SubRequest {
    #[allow(irrefutable_let_patterns)]
    pub fn into_foo(self) -> Option<(String, SubFooResponder)> {
        if let SubRequest::Foo { s, responder } = self {
            Some((s, responder))
        } else {
            None
        }
    }

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

pub struct SubEncoder;

impl SubEncoder {
    pub fn encode_foo_request<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
        mut in_s: &str,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x45602cf3b581d6ab);
        let mut body = (in_s,);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };
        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.inheritance/subFooRequest");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);
        Ok(())
    }
    pub fn encode_foo_response<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
        mut in_y: i64,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x45602cf3b581d6ab);
        let mut body = (in_y,);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };

        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.inheritance/subFooResponse");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);

        Ok(())
    }
}

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

impl SubControlHandle {
    /// Set the server to shutdown. The underlying channel is only closed the
    /// next time the stream is polled.
    pub fn shutdown(&self) {
        self.inner.shutdown()
    }

    pub fn shutdown_with_epitaph(&self, status: zx_status::Status) {
        self.inner.shutdown_with_epitaph(status)
    }
}
#[must_use = "FIDL methods require a response to be sent"]
#[derive(Debug)]
pub struct SubFooResponder {
    control_handle: std::mem::ManuallyDrop<SubControlHandle>,
    tx_id: u32,
    ordinal: u64,
}

/// Set the the channel to be shutdown (see [`SubControlHandle::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 SubFooResponder {
    fn drop(&mut self) {
        self.control_handle.shutdown();
        // Safety: drops once, never accessed again
        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
    }
}

impl SubFooResponder {
    pub fn control_handle(&self) -> &SubControlHandle {
        &self.control_handle
    }

    /// Drop the Responder without setting the channel to shutdown.
    ///
    /// This method shouldn't normally be used-- instead, send a response
    /// to prevent the channel from shutting down.
    pub 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);
    }

    /// Sends a response to the FIDL transaction.
    ///
    /// Sets the channel to shutdown if an error occurs.
    pub fn send(self, mut y: i64) -> Result<(), fidl::Error> {
        let r = self.send_raw(y);
        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 y: i64) -> Result<(), fidl::Error> {
        let r = self.send_raw(y);
        self.drop_without_shutdown();
        r
    }

    fn send_raw(&self, mut y: i64) -> Result<(), fidl::Error> {
        let mut response = (y);

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

        fidl::encoding::with_tls_encode_buf(|bytes, handles| {
            fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.inheritance/subFooResponse");
            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(())
        })
    }
}
