// 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, Clone, PartialEq)]
pub enum FlexibleFoo {
    S(String),
    I(i32),
    #[deprecated = "Use `FlexibleFoo::unknown()` to construct and `FlexibleFooUnknown!()` to exhaustively match."]
    #[doc(hidden)]
    __Unknown {
        ordinal: u64,
        bytes: Vec<u8>,
    },
}
/// Pattern that matches an unknown FlexibleFoo member.
#[macro_export]
macro_rules! FlexibleFooUnknown {
    () => {
        _
    };
}
fidl_xunion! {
    name: FlexibleFoo,
    members: [
        S {
            ty: String,
            ordinal: 1,
        },
        I {
            ty: i32,
            ordinal: 2,
        },
    ],
    value_unknown_member: __Unknown,
}

#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum StrictFoo {
    S(String),
    I(i32),
}
fidl_xunion! {
    name: StrictFoo,
    members: [
        S {
            ty: String,
            ordinal: 1,
        },
        I {
            ty: i32,
            ordinal: 2,
        },
    ],
    strict_value: true,
}

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

impl fidl::endpoints::ServiceMarker for ProtocolMarker {
    type Proxy = ProtocolProxy;
    type RequestStream = ProtocolRequestStream;
    const DEBUG_NAME: &'static str = "(anonymous) Protocol";
}

pub trait ProtocolProxyInterface: Send + Sync {
    type RequestStrictResponseFlexibleResponseFut: std::future::Future<Output = Result<(FlexibleFoo), fidl::Error>>
        + Send;
    fn r#request_strict_response_flexible(
        &self,
        s: &mut StrictFoo,
    ) -> Self::RequestStrictResponseFlexibleResponseFut;
    type RequestFlexibleResponseStrictResponseFut: std::future::Future<Output = Result<(StrictFoo), fidl::Error>>
        + Send;
    fn r#request_flexible_response_strict(
        &self,
        s: &mut FlexibleFoo,
    ) -> Self::RequestFlexibleResponseStrictResponseFut;
}

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

#[cfg(target_os = "fuchsia")]
impl ProtocolSynchronousProxy {
    pub fn new(channel: fidl::Channel) -> Self {
        let service_name = <ProtocolMarker 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#request_strict_response_flexible(
        &mut self,
        mut s: &mut StrictFoo,
        ___deadline: zx::Time,
    ) -> Result<(FlexibleFoo), fidl::Error> {
        let _value: (FlexibleFoo,) =
            self.client.send_query(&mut (s), 0x3c5330c58686011a, ___deadline)?;
        Ok(_value.0)
    }
    pub fn r#request_flexible_response_strict(
        &mut self,
        mut s: &mut FlexibleFoo,
        ___deadline: zx::Time,
    ) -> Result<(StrictFoo), fidl::Error> {
        let _value: (StrictFoo,) =
            self.client.send_query(&mut (s), 0x3cb49d8f6e204f76, ___deadline)?;
        Ok(_value.0)
    }
}

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

impl fidl::endpoints::Proxy for ProtocolProxy {
    type Service = ProtocolMarker;

    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 ProtocolProxy {
    /// Create a new Proxy for Protocol
    pub fn new(channel: fidl::AsyncChannel) -> Self {
        let service_name = <ProtocolMarker 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 Protocol protocol
    ///
    /// # Panics
    ///
    /// Panics if the event stream was already taken.
    pub fn take_event_stream(&self) -> ProtocolEventStream {
        ProtocolEventStream { event_receiver: self.client.take_event_receiver() }
    }
    pub fn r#request_strict_response_flexible(
        &self,
        mut s: &mut StrictFoo,
    ) -> fidl::client::QueryResponseFut<(FlexibleFoo)> {
        ProtocolProxyInterface::r#request_strict_response_flexible(self, s)
    }
    pub fn r#request_flexible_response_strict(
        &self,
        mut s: &mut FlexibleFoo,
    ) -> fidl::client::QueryResponseFut<(StrictFoo)> {
        ProtocolProxyInterface::r#request_flexible_response_strict(self, s)
    }
}

impl ProtocolProxyInterface for ProtocolProxy {
    type RequestStrictResponseFlexibleResponseFut = fidl::client::QueryResponseFut<(FlexibleFoo)>;
    fn r#request_strict_response_flexible(
        &self,
        mut s: &mut StrictFoo,
    ) -> Self::RequestStrictResponseFlexibleResponseFut {
        fn transform(
            result: Result<(FlexibleFoo,), fidl::Error>,
        ) -> Result<(FlexibleFoo), fidl::Error> {
            result.map(|_value| _value.0)
        }
        let send_result = self.client.call_send_raw_query(&mut (s), 0x3c5330c58686011a);
        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 RequestFlexibleResponseStrictResponseFut = fidl::client::QueryResponseFut<(StrictFoo)>;
    fn r#request_flexible_response_strict(
        &self,
        mut s: &mut FlexibleFoo,
    ) -> Self::RequestFlexibleResponseStrictResponseFut {
        fn transform(
            result: Result<(StrictFoo,), fidl::Error>,
        ) -> Result<(StrictFoo), fidl::Error> {
            result.map(|_value| _value.0)
        }
        let send_result = self.client.call_send_raw_query(&mut (s), 0x3cb49d8f6e204f76);
        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 ProtocolEventStream {
    event_receiver: fidl::client::EventReceiver,
}

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

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

impl futures::Stream for ProtocolEventStream {
    type Item = Result<ProtocolEvent, 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: <ProtocolMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
            }),
        }))
    }
}

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

impl ProtocolEvent {}

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

impl<'a> ProtocolServerSender<'a> {
    pub fn new(channel: &'a fidl::Channel) -> Self {
        Self { channel }
    }
    pub fn send_request_strict_response_flexible_response(
        &self,
        txid: fidl::client::Txid,
        mut f: &mut FlexibleFoo,
    ) -> Result<(), fidl::Error> {
        fidl::encoding::with_tls_encode_buf(|bytes_, handles_| {
            ProtocolEncoder::encode_request_strict_response_flexible_response(
                bytes_,
                handles_,
                txid.as_raw_id(),
                f,
            )?;
            self.channel
                .write_etc(&*bytes_, &mut *handles_)
                .map_err(fidl::Error::ServerResponseWrite)?;
            Ok(())
        })
    }
    pub fn send_request_flexible_response_strict_response(
        &self,
        txid: fidl::client::Txid,
        mut f: &mut StrictFoo,
    ) -> Result<(), fidl::Error> {
        fidl::encoding::with_tls_encode_buf(|bytes_, handles_| {
            ProtocolEncoder::encode_request_flexible_response_strict_response(
                bytes_,
                handles_,
                txid.as_raw_id(),
                f,
            )?;
            self.channel
                .write_etc(&*bytes_, &mut *handles_)
                .map_err(fidl::Error::ServerResponseWrite)?;
            Ok(())
        })
    }
}

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

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

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

impl fidl::endpoints::RequestStream for ProtocolRequestStream {
    type Service = ProtocolMarker;

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

    /// ControlHandle for the remote connection
    fn control_handle(&self) -> Self::ControlHandle {
        ProtocolControlHandle { 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 ProtocolRequestStream {
    type Item = Result<ProtocolRequest, 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 ProtocolRequestStream 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() {
                0x3c5330c58686011a => {
                    let mut req: (StrictFoo,) = fidl::encoding::Decodable::new_empty();
                    fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.requestflexibleenvelope/ProtocolRequestStrictResponseFlexibleRequest");
                    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 = ProtocolControlHandle { inner: this.inner.clone() };

                    Ok(ProtocolRequest::RequestStrictResponseFlexible {
                        s: req.0,
                        responder: ProtocolRequestStrictResponseFlexibleResponder {
                            control_handle: std::mem::ManuallyDrop::new(control_handle),
                            tx_id: header.tx_id(),
                            ordinal: header.ordinal(),
                        },
                    })
                }
                0x3cb49d8f6e204f76 => {
                    let mut req: (FlexibleFoo,) = fidl::encoding::Decodable::new_empty();
                    fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.requestflexibleenvelope/ProtocolRequestFlexibleResponseStrictRequest");
                    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 = ProtocolControlHandle { inner: this.inner.clone() };

                    Ok(ProtocolRequest::RequestFlexibleResponseStrict {
                        s: req.0,
                        responder: ProtocolRequestFlexibleResponseStrictResponder {
                            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: <ProtocolMarker 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 ProtocolRequest instead")]
pub enum ProtocolRequestMessage {
    RequestStrictResponseFlexible { s: StrictFoo, tx_id: fidl::client::Txid },
    RequestFlexibleResponseStrict { s: FlexibleFoo, tx_id: fidl::client::Txid },
}

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

        match header.ordinal() {
            0x3c5330c58686011a => {
                let mut out_tuple: (StrictFoo,) = fidl::encoding::Decodable::new_empty();
                fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.requestflexibleenvelope/ProtocolRequestStrictResponseFlexibleRequest");
                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(ProtocolRequestMessage::RequestStrictResponseFlexible {
                    s: out_tuple.0,
                    tx_id: header.tx_id().into(),
                })
            }
            0x3cb49d8f6e204f76 => {
                let mut out_tuple: (FlexibleFoo,) = fidl::encoding::Decodable::new_empty();
                fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.requestflexibleenvelope/ProtocolRequestFlexibleResponseStrictRequest");
                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(ProtocolRequestMessage::RequestFlexibleResponseStrict {
                    s: out_tuple.0,
                    tx_id: header.tx_id().into(),
                })
            }
            _ => Err(fidl::Error::UnknownOrdinal {
                ordinal: header.ordinal(),
                service_name: <ProtocolMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
            }),
        }
    }
}
#[derive(Debug)]
pub enum ProtocolRequest {
    RequestStrictResponseFlexible {
        s: StrictFoo,
        responder: ProtocolRequestStrictResponseFlexibleResponder,
    },
    RequestFlexibleResponseStrict {
        s: FlexibleFoo,
        responder: ProtocolRequestFlexibleResponseStrictResponder,
    },
}

impl ProtocolRequest {
    #[allow(irrefutable_let_patterns)]
    pub fn into_request_strict_response_flexible(
        self,
    ) -> Option<(StrictFoo, ProtocolRequestStrictResponseFlexibleResponder)> {
        if let ProtocolRequest::RequestStrictResponseFlexible { s, responder } = self {
            Some((s, responder))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_request_flexible_response_strict(
        self,
    ) -> Option<(FlexibleFoo, ProtocolRequestFlexibleResponseStrictResponder)> {
        if let ProtocolRequest::RequestFlexibleResponseStrict { s, responder } = self {
            Some((s, responder))
        } else {
            None
        }
    }

    /// Name of the method defined in FIDL
    pub fn method_name(&self) -> &'static str {
        match *self {
            ProtocolRequest::RequestStrictResponseFlexible { .. } => {
                "request_strict_response_flexible"
            }
            ProtocolRequest::RequestFlexibleResponseStrict { .. } => {
                "request_flexible_response_strict"
            }
        }
    }
}

pub struct ProtocolEncoder;

impl ProtocolEncoder {
    pub fn encode_request_strict_response_flexible_request<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
        mut in_s: &mut StrictFoo,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x3c5330c58686011a);
        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.requestflexibleenvelope/ProtocolRequestStrictResponseFlexibleRequest");
        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_request_strict_response_flexible_response<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
        mut in_f: &mut FlexibleFoo,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x3c5330c58686011a);
        let mut body = (in_f,);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };

        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.requestflexibleenvelope/ProtocolRequestStrictResponseFlexibleResponse");
        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_request_flexible_response_strict_request<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
        mut in_s: &mut FlexibleFoo,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x3cb49d8f6e204f76);
        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.requestflexibleenvelope/ProtocolRequestFlexibleResponseStrictRequest");
        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_request_flexible_response_strict_response<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
        mut in_f: &mut StrictFoo,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x3cb49d8f6e204f76);
        let mut body = (in_f,);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };

        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.requestflexibleenvelope/ProtocolRequestFlexibleResponseStrictResponse");
        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 ProtocolControlHandle {
    inner: std::sync::Arc<fidl::ServeInner>,
}

impl ProtocolControlHandle {
    /// 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 ProtocolRequestStrictResponseFlexibleResponder {
    control_handle: std::mem::ManuallyDrop<ProtocolControlHandle>,
    tx_id: u32,
    ordinal: u64,
}

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

impl ProtocolRequestStrictResponseFlexibleResponder {
    pub fn control_handle(&self) -> &ProtocolControlHandle {
        &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 f: &mut FlexibleFoo) -> Result<(), fidl::Error> {
        let r = self.send_raw(f);
        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 f: &mut FlexibleFoo) -> Result<(), fidl::Error> {
        let r = self.send_raw(f);
        self.drop_without_shutdown();
        r
    }

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

        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.requestflexibleenvelope/ProtocolRequestStrictResponseFlexibleResponse");
            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 ProtocolRequestFlexibleResponseStrictResponder {
    control_handle: std::mem::ManuallyDrop<ProtocolControlHandle>,
    tx_id: u32,
    ordinal: u64,
}

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

impl ProtocolRequestFlexibleResponseStrictResponder {
    pub fn control_handle(&self) -> &ProtocolControlHandle {
        &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 f: &mut StrictFoo) -> Result<(), fidl::Error> {
        let r = self.send_raw(f);
        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 f: &mut StrictFoo) -> Result<(), fidl::Error> {
        let r = self.send_raw(f);
        self.drop_without_shutdown();
        r
    }

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

        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.requestflexibleenvelope/ProtocolRequestFlexibleResponseStrictResponse");
            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(())
        })
    }
}
