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

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

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

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

const _FIDL_TRACE_BINDINGS_RUST: u32 = 6;

pub type ExampleUseOfErrorSyntaxCallWhichMayFailResult = std::result::Result<(i64), u32>;

pub type ExampleUseOfErrorSyntaxCallWhichMayFailResultHandleWrapper =
    std::result::Result<(i64,), u32>;

#[derive(
    Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, zerocopy::AsBytes, zerocopy::FromBytes,
)]
#[repr(C)]
pub struct ExampleUseOfErrorSyntaxCallWhichMayFailResponse {
    pub value: i64,
}

impl fidl::encoding::Persistable for ExampleUseOfErrorSyntaxCallWhichMayFailResponse {}

fidl_struct_copy! {
  name: ExampleUseOfErrorSyntaxCallWhichMayFailResponse,
  members: [
    value {
      ty: i64,
      offset_v1: 0,
      offset_v2: 0,
    },
  ],
  padding_v1: [],
  padding_v2: [],
  size_v1: 8,
  size_v2: 8,
  align_v1: 8,
  align_v2: 8,
}

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

impl fidl::endpoints::ProtocolMarker for ExampleUseOfErrorSyntaxMarker {
    type Proxy = ExampleUseOfErrorSyntaxProxy;
    type RequestStream = ExampleUseOfErrorSyntaxRequestStream;
    const DEBUG_NAME: &'static str = "(anonymous) ExampleUseOfErrorSyntax";
}

pub trait ExampleUseOfErrorSyntaxProxyInterface: Send + Sync {
    type ComposedCallWhichMayFailResponseFut: std::future::Future<Output = Result<(fidl_fidl_test_errorsyntax_parent::ParentUsesErrorSyntaxComposedCallWhichMayFailResult), fidl::Error>> + Send;
    fn r#composed_call_which_may_fail(&self, s: &str) -> Self::ComposedCallWhichMayFailResponseFut;
    type CallWhichMayFailResponseFut: std::future::Future<
            Output = Result<(ExampleUseOfErrorSyntaxCallWhichMayFailResult), fidl::Error>,
        > + Send;
    fn r#call_which_may_fail(&self, s: &str) -> Self::CallWhichMayFailResponseFut;
}

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

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

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

    /// Waits until an event arrives and returns it. It is safe for other
    /// threads to make concurrent requests while waiting for an event.
    pub fn wait_for_event(
        &self,
        deadline: zx::Time,
    ) -> Result<ExampleUseOfErrorSyntaxEvent, fidl::Error> {
        ExampleUseOfErrorSyntaxEvent::decode(self.client.wait_for_event(deadline)?)
    }
    pub fn r#composed_call_which_may_fail(
        &self,
        mut s: &str,
        ___deadline: zx::Time,
    ) -> Result<
        (fidl_fidl_test_errorsyntax_parent::ParentUsesErrorSyntaxComposedCallWhichMayFailResult),
        fidl::Error,
    > {
        let _value: (
            fidl_fidl_test_errorsyntax_parent::ParentUsesErrorSyntaxComposedCallWhichMayFailResult,
        ) = self.client.send_query(&mut (s), 0x71f05a4555fd5234, ___deadline)?;
        Ok(_value.0)
    }
    pub fn r#call_which_may_fail(
        &self,
        mut s: &str,
        ___deadline: zx::Time,
    ) -> Result<(ExampleUseOfErrorSyntaxCallWhichMayFailResult), fidl::Error> {
        let _value: (ExampleUseOfErrorSyntaxCallWhichMayFailResultHandleWrapper) =
            self.client.send_query(&mut (s), 0x67314da4a7f84897, ___deadline)?;
        Ok(_value.map(|_value| _value.0))
    }
}

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

impl fidl::endpoints::Proxy for ExampleUseOfErrorSyntaxProxy {
    type Protocol = ExampleUseOfErrorSyntaxMarker;

    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 ExampleUseOfErrorSyntaxProxy {
    /// Create a new Proxy for ExampleUseOfErrorSyntax
    pub fn new(channel: fidl::AsyncChannel) -> Self {
        let protocol_name =
            <ExampleUseOfErrorSyntaxMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
        Self { client: fidl::client::Client::new(channel, protocol_name) }
    }

    /// Get a Stream of events from the remote end of the ExampleUseOfErrorSyntax protocol
    ///
    /// # Panics
    ///
    /// Panics if the event stream was already taken.
    pub fn take_event_stream(&self) -> ExampleUseOfErrorSyntaxEventStream {
        ExampleUseOfErrorSyntaxEventStream { event_receiver: self.client.take_event_receiver() }
    }
    pub fn r#composed_call_which_may_fail(
        &self,
        mut s: &str,
    ) -> fidl::client::QueryResponseFut<
        (fidl_fidl_test_errorsyntax_parent::ParentUsesErrorSyntaxComposedCallWhichMayFailResult),
    > {
        ExampleUseOfErrorSyntaxProxyInterface::r#composed_call_which_may_fail(self, s)
    }
    pub fn r#call_which_may_fail(
        &self,
        mut s: &str,
    ) -> fidl::client::QueryResponseFut<(ExampleUseOfErrorSyntaxCallWhichMayFailResult)> {
        ExampleUseOfErrorSyntaxProxyInterface::r#call_which_may_fail(self, s)
    }
}

impl ExampleUseOfErrorSyntaxProxyInterface for ExampleUseOfErrorSyntaxProxy {
    type ComposedCallWhichMayFailResponseFut = fidl::client::QueryResponseFut<
        (fidl_fidl_test_errorsyntax_parent::ParentUsesErrorSyntaxComposedCallWhichMayFailResult),
    >;
    fn r#composed_call_which_may_fail(
        &self,
        mut s: &str,
    ) -> Self::ComposedCallWhichMayFailResponseFut {
		fn transform(result: Result<(
			fidl_fidl_test_errorsyntax_parent::ParentUsesErrorSyntaxComposedCallWhichMayFailResult,
        ), fidl::Error>) -> Result<(fidl_fidl_test_errorsyntax_parent::ParentUsesErrorSyntaxComposedCallWhichMayFailResult), fidl::Error>{
            result.map(|_value| _value.0)
        }
        let send_result = self.client.call_send_raw_query(&mut (s), 0x71f05a4555fd5234);
        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 CallWhichMayFailResponseFut =
        fidl::client::QueryResponseFut<(ExampleUseOfErrorSyntaxCallWhichMayFailResult)>;
    fn r#call_which_may_fail(&self, mut s: &str) -> Self::CallWhichMayFailResponseFut {
        fn transform(
            result: Result<
                (ExampleUseOfErrorSyntaxCallWhichMayFailResultHandleWrapper),
                fidl::Error,
            >,
        ) -> Result<(ExampleUseOfErrorSyntaxCallWhichMayFailResult), fidl::Error> {
            result.map(|_value| _value.map(|_value| _value.0))
        }
        let send_result = self.client.call_send_raw_query(&mut (s), 0x67314da4a7f84897);
        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 ExampleUseOfErrorSyntaxEventStream {
    event_receiver: fidl::client::EventReceiver,
}

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

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

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

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

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

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

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

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

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

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

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

impl fidl::endpoints::RequestStream for ExampleUseOfErrorSyntaxRequestStream {
    type Protocol = ExampleUseOfErrorSyntaxMarker;
    type ControlHandle = ExampleUseOfErrorSyntaxControlHandle;

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

    fn control_handle(&self) -> Self::ControlHandle {
        ExampleUseOfErrorSyntaxControlHandle { 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 ExampleUseOfErrorSyntaxRequestStream {
    type Item = Result<ExampleUseOfErrorSyntaxRequest, 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 ExampleUseOfErrorSyntaxRequestStream 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() {
				0x71f05a4555fd5234 => {
					let mut req: (String,) = fidl::encoding::Decodable::new_empty();
					fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.errorsyntax/ExampleUseOfErrorSyntaxComposedCallWhichMayFailRequest");
					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 = ExampleUseOfErrorSyntaxControlHandle {
						inner: this.inner.clone(),
					};

					Ok(ExampleUseOfErrorSyntaxRequest::ComposedCallWhichMayFail {s: req.0,responder:ExampleUseOfErrorSyntaxComposedCallWhichMayFailResponder {
								control_handle: std::mem::ManuallyDrop::new(control_handle),
								tx_id: header.tx_id(),
								ordinal: header.ordinal(),
							},})
				}
				0x67314da4a7f84897 => {
					let mut req: (String,) = fidl::encoding::Decodable::new_empty();
					fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.errorsyntax/ExampleUseOfErrorSyntaxCallWhichMayFailRequest");
					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 = ExampleUseOfErrorSyntaxControlHandle {
						inner: this.inner.clone(),
					};

					Ok(ExampleUseOfErrorSyntaxRequest::CallWhichMayFail {s: req.0,responder:ExampleUseOfErrorSyntaxCallWhichMayFailResponder {
								control_handle: std::mem::ManuallyDrop::new(control_handle),
								tx_id: header.tx_id(),
								ordinal: header.ordinal(),
							},})
				}
				_ => Err(fidl::Error::UnknownOrdinal {
					ordinal: header.ordinal(),
					protocol_name: <ExampleUseOfErrorSyntaxMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
				}),
			}))
        })
    }
}
#[derive(Debug)]
pub enum ExampleUseOfErrorSyntaxRequest {
    ComposedCallWhichMayFail {
        s: String,
        responder: ExampleUseOfErrorSyntaxComposedCallWhichMayFailResponder,
    },
    CallWhichMayFail {
        s: String,
        responder: ExampleUseOfErrorSyntaxCallWhichMayFailResponder,
    },
}

impl ExampleUseOfErrorSyntaxRequest {
    #[allow(irrefutable_let_patterns)]
    pub fn into_composed_call_which_may_fail(
        self,
    ) -> Option<(String, ExampleUseOfErrorSyntaxComposedCallWhichMayFailResponder)> {
        if let ExampleUseOfErrorSyntaxRequest::ComposedCallWhichMayFail { s, responder } = self {
            Some((s, responder))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_call_which_may_fail(
        self,
    ) -> Option<(String, ExampleUseOfErrorSyntaxCallWhichMayFailResponder)> {
        if let ExampleUseOfErrorSyntaxRequest::CallWhichMayFail { s, responder } = self {
            Some((s, responder))
        } else {
            None
        }
    }

    /// Name of the method defined in FIDL
    pub fn method_name(&self) -> &'static str {
        match *self {
            ExampleUseOfErrorSyntaxRequest::ComposedCallWhichMayFail { .. } => {
                "composed_call_which_may_fail"
            }
            ExampleUseOfErrorSyntaxRequest::CallWhichMayFail { .. } => "call_which_may_fail",
        }
    }
}

pub struct ExampleUseOfErrorSyntaxEncoder;

impl ExampleUseOfErrorSyntaxEncoder {
    pub fn encode_composed_call_which_may_fail_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, 0x71f05a4555fd5234);
        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.errorsyntax/ExampleUseOfErrorSyntaxComposedCallWhichMayFailRequest");
        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_composed_call_which_may_fail_response<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
        mut in_result: &mut fidl_fidl_test_errorsyntax_parent::ParentUsesErrorSyntaxComposedCallWhichMayFailResult,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x71f05a4555fd5234);
        let mut body = ((in_result),);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };

        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.errorsyntax/ExampleUseOfErrorSyntaxComposedCallWhichMayFailResponse");
        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_call_which_may_fail_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, 0x67314da4a7f84897);
        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.errorsyntax/ExampleUseOfErrorSyntaxCallWhichMayFailRequest");
        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_call_which_may_fail_response<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
        mut in_result: &mut ExampleUseOfErrorSyntaxCallWhichMayFailResult,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x67314da4a7f84897);
        let mut body = ((in_result),);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };

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

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

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

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

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

impl fidl::endpoints::Responder for ExampleUseOfErrorSyntaxComposedCallWhichMayFailResponder {
    type ControlHandle = ExampleUseOfErrorSyntaxControlHandle;

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

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

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

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

        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.errorsyntax/ExampleUseOfErrorSyntaxComposedCallWhichMayFailResponse");
            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 ExampleUseOfErrorSyntaxCallWhichMayFailResponder {
    control_handle: std::mem::ManuallyDrop<ExampleUseOfErrorSyntaxControlHandle>,
    tx_id: u32,
    ordinal: u64,
}

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

impl fidl::endpoints::Responder for ExampleUseOfErrorSyntaxCallWhichMayFailResponder {
    type ControlHandle = ExampleUseOfErrorSyntaxControlHandle;

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

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

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

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

        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.errorsyntax/ExampleUseOfErrorSyntaxCallWhichMayFailResponse");
            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(())
        })
    }
}
