// DO NOT EDIT: This file is machine-generated by fidlgen
#![warn(clippy::all)]
#![allow(unused_parens, unused_variables, unused_mut, unused_imports, unreachable_code)]

pub mod natural {

    pub use fidl_next_common_test_protocolrequest::natural::*;

    #[derive(Debug, PartialEq)]
    #[repr(C)]
    pub struct ParentGetChildResponse {
        pub c: ::fidl_next::ClientEnd<crate::Child, ::fidl_next::fuchsia::zx::Channel>,
    }

    unsafe impl<___E> ::fidl_next::Encode<crate::wire::ParentGetChildResponse, ___E>
        for ParentGetChildResponse
    where
        ___E: ::fidl_next::encoder::InternalHandleEncoder + ?Sized,
        ___E: ::fidl_next::fuchsia::HandleEncoder,
    {
        const COPY_OPTIMIZATION: ::fidl_next::CopyOptimization<
            Self,
            crate::wire::ParentGetChildResponse,
        > = unsafe {
            ::fidl_next::CopyOptimization::enable_if(
            true

                && <
                    ::fidl_next::ClientEnd<crate::Child, ::fidl_next::fuchsia::zx::Channel> as ::fidl_next::Encode<::fidl_next::ClientEnd<crate::Child, ::fidl_next::wire::fuchsia::Channel>, ___E>
                >::COPY_OPTIMIZATION.is_enabled()

        )
        };

        #[inline]
        fn encode(
            self,
            encoder_: &mut ___E,
            out_: &mut ::core::mem::MaybeUninit<crate::wire::ParentGetChildResponse>,
            _: (),
        ) -> ::core::result::Result<(), ::fidl_next::EncodeError> {
            ::fidl_next::munge! {
                let crate::wire::ParentGetChildResponse {
                    c,

                } = out_;
            }

            ::fidl_next::Encode::encode(self.c, encoder_, c, ())?;

            let mut _field = unsafe { ::fidl_next::Slot::new_unchecked(c.as_mut_ptr()) };

            Ok(())
        }
    }

    unsafe impl<___E>
        ::fidl_next::EncodeOption<
            ::fidl_next::wire::Box<'static, crate::wire::ParentGetChildResponse>,
            ___E,
        > for ParentGetChildResponse
    where
        ___E: ::fidl_next::Encoder + ?Sized,
        ParentGetChildResponse: ::fidl_next::Encode<crate::wire::ParentGetChildResponse, ___E>,
    {
        #[inline]
        fn encode_option(
            this: ::core::option::Option<Self>,
            encoder: &mut ___E,
            out: &mut ::core::mem::MaybeUninit<
                ::fidl_next::wire::Box<'static, crate::wire::ParentGetChildResponse>,
            >,
            _: (),
        ) -> ::core::result::Result<(), ::fidl_next::EncodeError> {
            if let Some(inner) = this {
                ::fidl_next::EncoderExt::encode_next(encoder, inner)?;
                ::fidl_next::wire::Box::encode_present(out);
            } else {
                ::fidl_next::wire::Box::encode_absent(out);
            }

            Ok(())
        }
    }

    impl ::fidl_next::FromWire<crate::wire::ParentGetChildResponse> for ParentGetChildResponse {
        const COPY_OPTIMIZATION: ::fidl_next::CopyOptimization<
            crate::wire::ParentGetChildResponse,
            Self,
        > = unsafe {
            ::fidl_next::CopyOptimization::enable_if(
            true

                && <
                    ::fidl_next::ClientEnd<crate::Child, ::fidl_next::fuchsia::zx::Channel> as ::fidl_next::FromWire<::fidl_next::ClientEnd<crate::Child, ::fidl_next::wire::fuchsia::Channel>>
                >::COPY_OPTIMIZATION.is_enabled()

        )
        };

        #[inline]
        fn from_wire(wire: crate::wire::ParentGetChildResponse) -> Self {
            Self { c: ::fidl_next::FromWire::from_wire(wire.c) }
        }
    }

    #[derive(Debug, PartialEq)]
    #[repr(C)]
    pub struct ParentGetChildRequestResponse {
        pub r: ::fidl_next::ServerEnd<crate::Child, ::fidl_next::fuchsia::zx::Channel>,
    }

    unsafe impl<___E> ::fidl_next::Encode<crate::wire::ParentGetChildRequestResponse, ___E>
        for ParentGetChildRequestResponse
    where
        ___E: ::fidl_next::encoder::InternalHandleEncoder + ?Sized,
        ___E: ::fidl_next::fuchsia::HandleEncoder,
    {
        const COPY_OPTIMIZATION: ::fidl_next::CopyOptimization<
            Self,
            crate::wire::ParentGetChildRequestResponse,
        > = unsafe {
            ::fidl_next::CopyOptimization::enable_if(
            true

                && <
                    ::fidl_next::ServerEnd<crate::Child, ::fidl_next::fuchsia::zx::Channel> as ::fidl_next::Encode<::fidl_next::ServerEnd<crate::Child, ::fidl_next::wire::fuchsia::Channel>, ___E>
                >::COPY_OPTIMIZATION.is_enabled()

        )
        };

        #[inline]
        fn encode(
            self,
            encoder_: &mut ___E,
            out_: &mut ::core::mem::MaybeUninit<crate::wire::ParentGetChildRequestResponse>,
            _: (),
        ) -> ::core::result::Result<(), ::fidl_next::EncodeError> {
            ::fidl_next::munge! {
                let crate::wire::ParentGetChildRequestResponse {
                    r,

                } = out_;
            }

            ::fidl_next::Encode::encode(self.r, encoder_, r, ())?;

            let mut _field = unsafe { ::fidl_next::Slot::new_unchecked(r.as_mut_ptr()) };

            Ok(())
        }
    }

    unsafe impl<___E>
        ::fidl_next::EncodeOption<
            ::fidl_next::wire::Box<'static, crate::wire::ParentGetChildRequestResponse>,
            ___E,
        > for ParentGetChildRequestResponse
    where
        ___E: ::fidl_next::Encoder + ?Sized,
        ParentGetChildRequestResponse:
            ::fidl_next::Encode<crate::wire::ParentGetChildRequestResponse, ___E>,
    {
        #[inline]
        fn encode_option(
            this: ::core::option::Option<Self>,
            encoder: &mut ___E,
            out: &mut ::core::mem::MaybeUninit<
                ::fidl_next::wire::Box<'static, crate::wire::ParentGetChildRequestResponse>,
            >,
            _: (),
        ) -> ::core::result::Result<(), ::fidl_next::EncodeError> {
            if let Some(inner) = this {
                ::fidl_next::EncoderExt::encode_next(encoder, inner)?;
                ::fidl_next::wire::Box::encode_present(out);
            } else {
                ::fidl_next::wire::Box::encode_absent(out);
            }

            Ok(())
        }
    }

    impl ::fidl_next::FromWire<crate::wire::ParentGetChildRequestResponse>
        for ParentGetChildRequestResponse
    {
        const COPY_OPTIMIZATION: ::fidl_next::CopyOptimization<
            crate::wire::ParentGetChildRequestResponse,
            Self,
        > = unsafe {
            ::fidl_next::CopyOptimization::enable_if(
            true

                && <
                    ::fidl_next::ServerEnd<crate::Child, ::fidl_next::fuchsia::zx::Channel> as ::fidl_next::FromWire<::fidl_next::ServerEnd<crate::Child, ::fidl_next::wire::fuchsia::Channel>>
                >::COPY_OPTIMIZATION.is_enabled()

        )
        };

        #[inline]
        fn from_wire(wire: crate::wire::ParentGetChildRequestResponse) -> Self {
            Self { r: ::fidl_next::FromWire::from_wire(wire.r) }
        }
    }

    #[derive(Debug, PartialEq)]
    #[repr(C)]
    pub struct ParentTakeChildRequest {
        pub c: ::fidl_next::ClientEnd<crate::Child, ::fidl_next::fuchsia::zx::Channel>,
    }

    unsafe impl<___E> ::fidl_next::Encode<crate::wire::ParentTakeChildRequest, ___E>
        for ParentTakeChildRequest
    where
        ___E: ::fidl_next::encoder::InternalHandleEncoder + ?Sized,
        ___E: ::fidl_next::fuchsia::HandleEncoder,
    {
        const COPY_OPTIMIZATION: ::fidl_next::CopyOptimization<
            Self,
            crate::wire::ParentTakeChildRequest,
        > = unsafe {
            ::fidl_next::CopyOptimization::enable_if(
            true

                && <
                    ::fidl_next::ClientEnd<crate::Child, ::fidl_next::fuchsia::zx::Channel> as ::fidl_next::Encode<::fidl_next::ClientEnd<crate::Child, ::fidl_next::wire::fuchsia::Channel>, ___E>
                >::COPY_OPTIMIZATION.is_enabled()

        )
        };

        #[inline]
        fn encode(
            self,
            encoder_: &mut ___E,
            out_: &mut ::core::mem::MaybeUninit<crate::wire::ParentTakeChildRequest>,
            _: (),
        ) -> ::core::result::Result<(), ::fidl_next::EncodeError> {
            ::fidl_next::munge! {
                let crate::wire::ParentTakeChildRequest {
                    c,

                } = out_;
            }

            ::fidl_next::Encode::encode(self.c, encoder_, c, ())?;

            let mut _field = unsafe { ::fidl_next::Slot::new_unchecked(c.as_mut_ptr()) };

            Ok(())
        }
    }

    unsafe impl<___E>
        ::fidl_next::EncodeOption<
            ::fidl_next::wire::Box<'static, crate::wire::ParentTakeChildRequest>,
            ___E,
        > for ParentTakeChildRequest
    where
        ___E: ::fidl_next::Encoder + ?Sized,
        ParentTakeChildRequest: ::fidl_next::Encode<crate::wire::ParentTakeChildRequest, ___E>,
    {
        #[inline]
        fn encode_option(
            this: ::core::option::Option<Self>,
            encoder: &mut ___E,
            out: &mut ::core::mem::MaybeUninit<
                ::fidl_next::wire::Box<'static, crate::wire::ParentTakeChildRequest>,
            >,
            _: (),
        ) -> ::core::result::Result<(), ::fidl_next::EncodeError> {
            if let Some(inner) = this {
                ::fidl_next::EncoderExt::encode_next(encoder, inner)?;
                ::fidl_next::wire::Box::encode_present(out);
            } else {
                ::fidl_next::wire::Box::encode_absent(out);
            }

            Ok(())
        }
    }

    impl ::fidl_next::FromWire<crate::wire::ParentTakeChildRequest> for ParentTakeChildRequest {
        const COPY_OPTIMIZATION: ::fidl_next::CopyOptimization<
            crate::wire::ParentTakeChildRequest,
            Self,
        > = unsafe {
            ::fidl_next::CopyOptimization::enable_if(
            true

                && <
                    ::fidl_next::ClientEnd<crate::Child, ::fidl_next::fuchsia::zx::Channel> as ::fidl_next::FromWire<::fidl_next::ClientEnd<crate::Child, ::fidl_next::wire::fuchsia::Channel>>
                >::COPY_OPTIMIZATION.is_enabled()

        )
        };

        #[inline]
        fn from_wire(wire: crate::wire::ParentTakeChildRequest) -> Self {
            Self { c: ::fidl_next::FromWire::from_wire(wire.c) }
        }
    }

    #[derive(Debug, PartialEq)]
    #[repr(C)]
    pub struct ParentTakeChildRequestRequest {
        pub r: ::fidl_next::ServerEnd<crate::Child, ::fidl_next::fuchsia::zx::Channel>,
    }

    unsafe impl<___E> ::fidl_next::Encode<crate::wire::ParentTakeChildRequestRequest, ___E>
        for ParentTakeChildRequestRequest
    where
        ___E: ::fidl_next::encoder::InternalHandleEncoder + ?Sized,
        ___E: ::fidl_next::fuchsia::HandleEncoder,
    {
        const COPY_OPTIMIZATION: ::fidl_next::CopyOptimization<
            Self,
            crate::wire::ParentTakeChildRequestRequest,
        > = unsafe {
            ::fidl_next::CopyOptimization::enable_if(
            true

                && <
                    ::fidl_next::ServerEnd<crate::Child, ::fidl_next::fuchsia::zx::Channel> as ::fidl_next::Encode<::fidl_next::ServerEnd<crate::Child, ::fidl_next::wire::fuchsia::Channel>, ___E>
                >::COPY_OPTIMIZATION.is_enabled()

        )
        };

        #[inline]
        fn encode(
            self,
            encoder_: &mut ___E,
            out_: &mut ::core::mem::MaybeUninit<crate::wire::ParentTakeChildRequestRequest>,
            _: (),
        ) -> ::core::result::Result<(), ::fidl_next::EncodeError> {
            ::fidl_next::munge! {
                let crate::wire::ParentTakeChildRequestRequest {
                    r,

                } = out_;
            }

            ::fidl_next::Encode::encode(self.r, encoder_, r, ())?;

            let mut _field = unsafe { ::fidl_next::Slot::new_unchecked(r.as_mut_ptr()) };

            Ok(())
        }
    }

    unsafe impl<___E>
        ::fidl_next::EncodeOption<
            ::fidl_next::wire::Box<'static, crate::wire::ParentTakeChildRequestRequest>,
            ___E,
        > for ParentTakeChildRequestRequest
    where
        ___E: ::fidl_next::Encoder + ?Sized,
        ParentTakeChildRequestRequest:
            ::fidl_next::Encode<crate::wire::ParentTakeChildRequestRequest, ___E>,
    {
        #[inline]
        fn encode_option(
            this: ::core::option::Option<Self>,
            encoder: &mut ___E,
            out: &mut ::core::mem::MaybeUninit<
                ::fidl_next::wire::Box<'static, crate::wire::ParentTakeChildRequestRequest>,
            >,
            _: (),
        ) -> ::core::result::Result<(), ::fidl_next::EncodeError> {
            if let Some(inner) = this {
                ::fidl_next::EncoderExt::encode_next(encoder, inner)?;
                ::fidl_next::wire::Box::encode_present(out);
            } else {
                ::fidl_next::wire::Box::encode_absent(out);
            }

            Ok(())
        }
    }

    impl ::fidl_next::FromWire<crate::wire::ParentTakeChildRequestRequest>
        for ParentTakeChildRequestRequest
    {
        const COPY_OPTIMIZATION: ::fidl_next::CopyOptimization<
            crate::wire::ParentTakeChildRequestRequest,
            Self,
        > = unsafe {
            ::fidl_next::CopyOptimization::enable_if(
            true

                && <
                    ::fidl_next::ServerEnd<crate::Child, ::fidl_next::fuchsia::zx::Channel> as ::fidl_next::FromWire<::fidl_next::ServerEnd<crate::Child, ::fidl_next::wire::fuchsia::Channel>>
                >::COPY_OPTIMIZATION.is_enabled()

        )
        };

        #[inline]
        fn from_wire(wire: crate::wire::ParentTakeChildRequestRequest) -> Self {
            Self { r: ::fidl_next::FromWire::from_wire(wire.r) }
        }
    }
}

pub mod wire {

    pub use fidl_next_common_test_protocolrequest::wire::*;

    /// The wire type corresponding to [`ParentGetChildResponse`].
    #[derive(Debug)]
    #[repr(C)]
    pub struct ParentGetChildResponse {
        pub c: ::fidl_next::ClientEnd<crate::Child, ::fidl_next::wire::fuchsia::Channel>,
    }

    static_assertions::const_assert_eq!(std::mem::size_of::<ParentGetChildResponse>(), 4);
    static_assertions::const_assert_eq!(std::mem::align_of::<ParentGetChildResponse>(), 4);

    static_assertions::const_assert_eq!(std::mem::offset_of!(ParentGetChildResponse, c), 0);

    impl ::fidl_next::Constrained for ParentGetChildResponse {
        type Constraint = ();

        fn validate(
            _: ::fidl_next::Slot<'_, Self>,
            _: Self::Constraint,
        ) -> Result<(), ::fidl_next::ValidationError> {
            Ok(())
        }
    }

    unsafe impl ::fidl_next::Wire for ParentGetChildResponse {
        type Narrowed<'de> = ParentGetChildResponse;

        #[inline]
        fn zero_padding(out_: &mut ::core::mem::MaybeUninit<Self>) {
            ::fidl_next::munge! {
                let Self {
                    c,

                } = &mut *out_;
            }

            ::fidl_next::Wire::zero_padding(c);
        }
    }

    unsafe impl<___D> ::fidl_next::Decode<___D> for ParentGetChildResponse
    where
        ___D: ::fidl_next::decoder::InternalHandleDecoder + ?Sized,
        ___D: ::fidl_next::fuchsia::HandleDecoder,
    {
        fn decode(
            slot_: ::fidl_next::Slot<'_, Self>,
            decoder_: &mut ___D,
            _: (),
        ) -> ::core::result::Result<(), ::fidl_next::DecodeError> {
            ::fidl_next::munge! {
                let Self {
                    mut c,

                } = slot_;
            }

            let _field = c.as_mut();

            ::fidl_next::Decode::decode(c.as_mut(), decoder_, ())?;

            Ok(())
        }
    }

    impl ::fidl_next::IntoNatural for ParentGetChildResponse {
        type Natural = crate::natural::ParentGetChildResponse;
    }

    /// The wire type corresponding to [`ParentGetChildRequestResponse`].
    #[derive(Debug)]
    #[repr(C)]
    pub struct ParentGetChildRequestResponse {
        pub r: ::fidl_next::ServerEnd<crate::Child, ::fidl_next::wire::fuchsia::Channel>,
    }

    static_assertions::const_assert_eq!(std::mem::size_of::<ParentGetChildRequestResponse>(), 4);
    static_assertions::const_assert_eq!(std::mem::align_of::<ParentGetChildRequestResponse>(), 4);

    static_assertions::const_assert_eq!(std::mem::offset_of!(ParentGetChildRequestResponse, r), 0);

    impl ::fidl_next::Constrained for ParentGetChildRequestResponse {
        type Constraint = ();

        fn validate(
            _: ::fidl_next::Slot<'_, Self>,
            _: Self::Constraint,
        ) -> Result<(), ::fidl_next::ValidationError> {
            Ok(())
        }
    }

    unsafe impl ::fidl_next::Wire for ParentGetChildRequestResponse {
        type Narrowed<'de> = ParentGetChildRequestResponse;

        #[inline]
        fn zero_padding(out_: &mut ::core::mem::MaybeUninit<Self>) {
            ::fidl_next::munge! {
                let Self {
                    r,

                } = &mut *out_;
            }

            ::fidl_next::Wire::zero_padding(r);
        }
    }

    unsafe impl<___D> ::fidl_next::Decode<___D> for ParentGetChildRequestResponse
    where
        ___D: ::fidl_next::decoder::InternalHandleDecoder + ?Sized,
        ___D: ::fidl_next::fuchsia::HandleDecoder,
    {
        fn decode(
            slot_: ::fidl_next::Slot<'_, Self>,
            decoder_: &mut ___D,
            _: (),
        ) -> ::core::result::Result<(), ::fidl_next::DecodeError> {
            ::fidl_next::munge! {
                let Self {
                    mut r,

                } = slot_;
            }

            let _field = r.as_mut();

            ::fidl_next::Decode::decode(r.as_mut(), decoder_, ())?;

            Ok(())
        }
    }

    impl ::fidl_next::IntoNatural for ParentGetChildRequestResponse {
        type Natural = crate::natural::ParentGetChildRequestResponse;
    }

    /// The wire type corresponding to [`ParentTakeChildRequest`].
    #[derive(Debug)]
    #[repr(C)]
    pub struct ParentTakeChildRequest {
        pub c: ::fidl_next::ClientEnd<crate::Child, ::fidl_next::wire::fuchsia::Channel>,
    }

    static_assertions::const_assert_eq!(std::mem::size_of::<ParentTakeChildRequest>(), 4);
    static_assertions::const_assert_eq!(std::mem::align_of::<ParentTakeChildRequest>(), 4);

    static_assertions::const_assert_eq!(std::mem::offset_of!(ParentTakeChildRequest, c), 0);

    impl ::fidl_next::Constrained for ParentTakeChildRequest {
        type Constraint = ();

        fn validate(
            _: ::fidl_next::Slot<'_, Self>,
            _: Self::Constraint,
        ) -> Result<(), ::fidl_next::ValidationError> {
            Ok(())
        }
    }

    unsafe impl ::fidl_next::Wire for ParentTakeChildRequest {
        type Narrowed<'de> = ParentTakeChildRequest;

        #[inline]
        fn zero_padding(out_: &mut ::core::mem::MaybeUninit<Self>) {
            ::fidl_next::munge! {
                let Self {
                    c,

                } = &mut *out_;
            }

            ::fidl_next::Wire::zero_padding(c);
        }
    }

    unsafe impl<___D> ::fidl_next::Decode<___D> for ParentTakeChildRequest
    where
        ___D: ::fidl_next::decoder::InternalHandleDecoder + ?Sized,
        ___D: ::fidl_next::fuchsia::HandleDecoder,
    {
        fn decode(
            slot_: ::fidl_next::Slot<'_, Self>,
            decoder_: &mut ___D,
            _: (),
        ) -> ::core::result::Result<(), ::fidl_next::DecodeError> {
            ::fidl_next::munge! {
                let Self {
                    mut c,

                } = slot_;
            }

            let _field = c.as_mut();

            ::fidl_next::Decode::decode(c.as_mut(), decoder_, ())?;

            Ok(())
        }
    }

    impl ::fidl_next::IntoNatural for ParentTakeChildRequest {
        type Natural = crate::natural::ParentTakeChildRequest;
    }

    /// The wire type corresponding to [`ParentTakeChildRequestRequest`].
    #[derive(Debug)]
    #[repr(C)]
    pub struct ParentTakeChildRequestRequest {
        pub r: ::fidl_next::ServerEnd<crate::Child, ::fidl_next::wire::fuchsia::Channel>,
    }

    static_assertions::const_assert_eq!(std::mem::size_of::<ParentTakeChildRequestRequest>(), 4);
    static_assertions::const_assert_eq!(std::mem::align_of::<ParentTakeChildRequestRequest>(), 4);

    static_assertions::const_assert_eq!(std::mem::offset_of!(ParentTakeChildRequestRequest, r), 0);

    impl ::fidl_next::Constrained for ParentTakeChildRequestRequest {
        type Constraint = ();

        fn validate(
            _: ::fidl_next::Slot<'_, Self>,
            _: Self::Constraint,
        ) -> Result<(), ::fidl_next::ValidationError> {
            Ok(())
        }
    }

    unsafe impl ::fidl_next::Wire for ParentTakeChildRequestRequest {
        type Narrowed<'de> = ParentTakeChildRequestRequest;

        #[inline]
        fn zero_padding(out_: &mut ::core::mem::MaybeUninit<Self>) {
            ::fidl_next::munge! {
                let Self {
                    r,

                } = &mut *out_;
            }

            ::fidl_next::Wire::zero_padding(r);
        }
    }

    unsafe impl<___D> ::fidl_next::Decode<___D> for ParentTakeChildRequestRequest
    where
        ___D: ::fidl_next::decoder::InternalHandleDecoder + ?Sized,
        ___D: ::fidl_next::fuchsia::HandleDecoder,
    {
        fn decode(
            slot_: ::fidl_next::Slot<'_, Self>,
            decoder_: &mut ___D,
            _: (),
        ) -> ::core::result::Result<(), ::fidl_next::DecodeError> {
            ::fidl_next::munge! {
                let Self {
                    mut r,

                } = slot_;
            }

            let _field = r.as_mut();

            ::fidl_next::Decode::decode(r.as_mut(), decoder_, ())?;

            Ok(())
        }
    }

    impl ::fidl_next::IntoNatural for ParentTakeChildRequestRequest {
        type Natural = crate::natural::ParentTakeChildRequestRequest;
    }
}

pub mod wire_optional {

    pub use fidl_next_common_test_protocolrequest::wire_optional::*;
}

pub mod generic {

    pub use fidl_next_common_test_protocolrequest::generic::*;

    /// The generic type corresponding to [`ParentGetChildResponse`].
    pub struct ParentGetChildResponse<T0> {
        pub c: T0,
    }

    unsafe impl<___E, T0> ::fidl_next::Encode<crate::wire::ParentGetChildResponse, ___E>
        for ParentGetChildResponse<T0>
    where
        ___E: ::fidl_next::encoder::InternalHandleEncoder + ?Sized,
        ___E: ::fidl_next::fuchsia::HandleEncoder,
        T0: ::fidl_next::Encode<
                ::fidl_next::ClientEnd<crate::Child, ::fidl_next::wire::fuchsia::Channel>,
                ___E,
            >,
    {
        #[inline]
        fn encode(
            self,
            encoder_: &mut ___E,
            out_: &mut ::core::mem::MaybeUninit<crate::wire::ParentGetChildResponse>,
            _: (),
        ) -> ::core::result::Result<(), ::fidl_next::EncodeError> {
            ::fidl_next::munge! {
                let crate::wire::ParentGetChildResponse {
                    c,

                } = out_;
            }

            ::fidl_next::Encode::encode(self.c, encoder_, c, ())?;

            Ok(())
        }
    }

    /// The generic type corresponding to [`ParentGetChildRequestResponse`].
    pub struct ParentGetChildRequestResponse<T0> {
        pub r: T0,
    }

    unsafe impl<___E, T0> ::fidl_next::Encode<crate::wire::ParentGetChildRequestResponse, ___E>
        for ParentGetChildRequestResponse<T0>
    where
        ___E: ::fidl_next::encoder::InternalHandleEncoder + ?Sized,
        ___E: ::fidl_next::fuchsia::HandleEncoder,
        T0: ::fidl_next::Encode<
                ::fidl_next::ServerEnd<crate::Child, ::fidl_next::wire::fuchsia::Channel>,
                ___E,
            >,
    {
        #[inline]
        fn encode(
            self,
            encoder_: &mut ___E,
            out_: &mut ::core::mem::MaybeUninit<crate::wire::ParentGetChildRequestResponse>,
            _: (),
        ) -> ::core::result::Result<(), ::fidl_next::EncodeError> {
            ::fidl_next::munge! {
                let crate::wire::ParentGetChildRequestResponse {
                    r,

                } = out_;
            }

            ::fidl_next::Encode::encode(self.r, encoder_, r, ())?;

            Ok(())
        }
    }

    /// The generic type corresponding to [`ParentTakeChildRequest`].
    pub struct ParentTakeChildRequest<T0> {
        pub c: T0,
    }

    unsafe impl<___E, T0> ::fidl_next::Encode<crate::wire::ParentTakeChildRequest, ___E>
        for ParentTakeChildRequest<T0>
    where
        ___E: ::fidl_next::encoder::InternalHandleEncoder + ?Sized,
        ___E: ::fidl_next::fuchsia::HandleEncoder,
        T0: ::fidl_next::Encode<
                ::fidl_next::ClientEnd<crate::Child, ::fidl_next::wire::fuchsia::Channel>,
                ___E,
            >,
    {
        #[inline]
        fn encode(
            self,
            encoder_: &mut ___E,
            out_: &mut ::core::mem::MaybeUninit<crate::wire::ParentTakeChildRequest>,
            _: (),
        ) -> ::core::result::Result<(), ::fidl_next::EncodeError> {
            ::fidl_next::munge! {
                let crate::wire::ParentTakeChildRequest {
                    c,

                } = out_;
            }

            ::fidl_next::Encode::encode(self.c, encoder_, c, ())?;

            Ok(())
        }
    }

    /// The generic type corresponding to [`ParentTakeChildRequestRequest`].
    pub struct ParentTakeChildRequestRequest<T0> {
        pub r: T0,
    }

    unsafe impl<___E, T0> ::fidl_next::Encode<crate::wire::ParentTakeChildRequestRequest, ___E>
        for ParentTakeChildRequestRequest<T0>
    where
        ___E: ::fidl_next::encoder::InternalHandleEncoder + ?Sized,
        ___E: ::fidl_next::fuchsia::HandleEncoder,
        T0: ::fidl_next::Encode<
                ::fidl_next::ServerEnd<crate::Child, ::fidl_next::wire::fuchsia::Channel>,
                ___E,
            >,
    {
        #[inline]
        fn encode(
            self,
            encoder_: &mut ___E,
            out_: &mut ::core::mem::MaybeUninit<crate::wire::ParentTakeChildRequestRequest>,
            _: (),
        ) -> ::core::result::Result<(), ::fidl_next::EncodeError> {
            ::fidl_next::munge! {
                let crate::wire::ParentTakeChildRequestRequest {
                    r,

                } = out_;
            }

            ::fidl_next::Encode::encode(self.r, encoder_, r, ())?;

            Ok(())
        }
    }
}

pub use self::natural::*;

/// The type corresponding to the Parent protocol.
#[derive(PartialEq, Debug)]
pub struct Parent;

#[cfg(target_os = "fuchsia")]
impl ::fidl_next::HasTransport for Parent {
    type Transport = ::fidl_next::fuchsia::zx::Channel;
}

pub mod parent {
    pub mod prelude {
        pub use crate::{
            Parent, ParentClientHandler, ParentLocalClientHandler, ParentLocalServerHandler,
            ParentServerHandler, parent,
        };

        pub use crate::natural::ParentGetChildRequestResponse;

        pub use crate::natural::ParentGetChildResponse;

        pub use crate::natural::ParentTakeChildRequest;

        pub use crate::natural::ParentTakeChildRequestRequest;
    }

    pub struct GetChild;

    impl ::fidl_next::Method for GetChild {
        const ORDINAL: u64 = 881818649151440699;
        const FLEXIBILITY: ::fidl_next::protocol::Flexibility =
            ::fidl_next::protocol::Flexibility::Strict;

        type Protocol = crate::Parent;

        type Request = ::fidl_next::wire::EmptyMessageBody;
    }

    impl ::fidl_next::TwoWayMethod for GetChild {
        type Response = crate::wire::ParentGetChildResponse;
    }

    impl<___R> ::fidl_next::Respond<___R> for GetChild {
        type Output = crate::generic::ParentGetChildResponse<___R>;

        fn respond(response: ___R) -> Self::Output {
            crate::generic::ParentGetChildResponse { c: response }
        }
    }

    pub struct GetChildRequest;

    impl ::fidl_next::Method for GetChildRequest {
        const ORDINAL: u64 = 1096855814967598201;
        const FLEXIBILITY: ::fidl_next::protocol::Flexibility =
            ::fidl_next::protocol::Flexibility::Strict;

        type Protocol = crate::Parent;

        type Request = ::fidl_next::wire::EmptyMessageBody;
    }

    impl ::fidl_next::TwoWayMethod for GetChildRequest {
        type Response = crate::wire::ParentGetChildRequestResponse;
    }

    impl<___R> ::fidl_next::Respond<___R> for GetChildRequest {
        type Output = crate::generic::ParentGetChildRequestResponse<___R>;

        fn respond(response: ___R) -> Self::Output {
            crate::generic::ParentGetChildRequestResponse { r: response }
        }
    }

    pub struct TakeChild;

    impl ::fidl_next::Method for TakeChild {
        const ORDINAL: u64 = 4470101341872267920;
        const FLEXIBILITY: ::fidl_next::protocol::Flexibility =
            ::fidl_next::protocol::Flexibility::Strict;

        type Protocol = crate::Parent;

        type Request = crate::wire::ParentTakeChildRequest;
    }

    pub struct TakeChildRequest;

    impl ::fidl_next::Method for TakeChildRequest {
        const ORDINAL: u64 = 2333981071306416007;
        const FLEXIBILITY: ::fidl_next::protocol::Flexibility =
            ::fidl_next::protocol::Flexibility::Strict;

        type Protocol = crate::Parent;

        type Request = crate::wire::ParentTakeChildRequestRequest;
    }

    mod ___detail {
        unsafe impl<___T> ::fidl_next::HasConnectionHandles<___T> for crate::Parent
        where
            ___T: ::fidl_next::Transport,
        {
            type Client = ParentClient<___T>;
            type Server = ParentServer<___T>;
        }

        /// The client for the `Parent` protocol.
        #[repr(transparent)]
        pub struct ParentClient<___T: ::fidl_next::Transport> {
            #[allow(dead_code)]
            client: ::fidl_next::protocol::Client<___T>,
        }

        impl<___T> ParentClient<___T>
        where
            ___T: ::fidl_next::Transport,
        {
            pub fn get_child(&self) -> ::fidl_next::TwoWayFuture<'_, super::GetChild, ___T> {
                ::fidl_next::TwoWayFuture::from_untyped(
                    self.client.send_two_way::<::fidl_next::wire::EmptyMessageBody>(
                        881818649151440699,
                        <super::GetChild as ::fidl_next::Method>::FLEXIBILITY,
                        (),
                    ),
                )
            }

            pub fn get_child_request(
                &self,
            ) -> ::fidl_next::TwoWayFuture<'_, super::GetChildRequest, ___T> {
                ::fidl_next::TwoWayFuture::from_untyped(
                    self.client.send_two_way::<::fidl_next::wire::EmptyMessageBody>(
                        1096855814967598201,
                        <super::GetChildRequest as ::fidl_next::Method>::FLEXIBILITY,
                        (),
                    ),
                )
            }

            pub fn take_child(
                &self,

                c: impl ::fidl_next::Encode<
                    ::fidl_next::ClientEnd<crate::Child, ::fidl_next::wire::fuchsia::Channel>,
                    <___T as ::fidl_next::Transport>::SendBuffer,
                >,
            ) -> ::fidl_next::SendFuture<'_, ___T>
            where
                <___T as ::fidl_next::Transport>::SendBuffer:
                    ::fidl_next::encoder::InternalHandleEncoder,
                <___T as ::fidl_next::Transport>::SendBuffer: ::fidl_next::fuchsia::HandleEncoder,
            {
                self.take_child_with(crate::generic::ParentTakeChildRequest { c })
            }

            pub fn take_child_with<___R>(&self, request: ___R) -> ::fidl_next::SendFuture<'_, ___T>
            where
                ___R: ::fidl_next::Encode<
                        crate::wire::ParentTakeChildRequest,
                        <___T as ::fidl_next::Transport>::SendBuffer,
                    >,
            {
                ::fidl_next::SendFuture::from_untyped(self.client.send_one_way(
                    4470101341872267920,
                    <super::TakeChild as ::fidl_next::Method>::FLEXIBILITY,
                    request,
                ))
            }

            pub fn take_child_request(
                &self,

                r: impl ::fidl_next::Encode<
                    ::fidl_next::ServerEnd<crate::Child, ::fidl_next::wire::fuchsia::Channel>,
                    <___T as ::fidl_next::Transport>::SendBuffer,
                >,
            ) -> ::fidl_next::SendFuture<'_, ___T>
            where
                <___T as ::fidl_next::Transport>::SendBuffer:
                    ::fidl_next::encoder::InternalHandleEncoder,
                <___T as ::fidl_next::Transport>::SendBuffer: ::fidl_next::fuchsia::HandleEncoder,
            {
                self.take_child_request_with(crate::generic::ParentTakeChildRequestRequest { r })
            }

            pub fn take_child_request_with<___R>(
                &self,
                request: ___R,
            ) -> ::fidl_next::SendFuture<'_, ___T>
            where
                ___R: ::fidl_next::Encode<
                        crate::wire::ParentTakeChildRequestRequest,
                        <___T as ::fidl_next::Transport>::SendBuffer,
                    >,
            {
                ::fidl_next::SendFuture::from_untyped(self.client.send_one_way(
                    2333981071306416007,
                    <super::TakeChildRequest as ::fidl_next::Method>::FLEXIBILITY,
                    request,
                ))
            }
        }

        /// The server for the `Parent` protocol.
        #[repr(transparent)]
        pub struct ParentServer<___T: ::fidl_next::Transport> {
            server: ::fidl_next::protocol::Server<___T>,
        }

        impl<___T> ParentServer<___T> where ___T: ::fidl_next::Transport {}
    }
}

#[diagnostic::on_unimplemented(
    note = "If {Self} implements the non-local ParentClientHandler trait, use `spawn_as_local` or the `Local` adapter type"
)]

/// A client handler for the Parent protocol.
///
/// See [`Parent`] for more details.
pub trait ParentLocalClientHandler<
    #[cfg(target_os = "fuchsia")] ___T: ::fidl_next::Transport = ::fidl_next::fuchsia::zx::Channel,
    #[cfg(not(target_os = "fuchsia"))] ___T: ::fidl_next::Transport,
>
{
}

impl<___H, ___T> ::fidl_next::DispatchLocalClientMessage<___H, ___T> for Parent
where
    ___H: ParentLocalClientHandler<___T>,
    ___T: ::fidl_next::Transport,
{
    async fn on_event(
        handler: &mut ___H,
        ordinal: u64,
        flexibility: ::fidl_next::protocol::Flexibility,
        body: ::fidl_next::Body<___T>,
    ) -> ::core::result::Result<(), ::fidl_next::ProtocolError<___T::Error>> {
        match ordinal {
            ordinal => Err(::fidl_next::ProtocolError::UnknownOrdinal(ordinal)),
        }
    }
}

#[diagnostic::on_unimplemented(
    note = "If {Self} implements the non-local ParentServerHandler trait, use `spawn_as_local` or the `Local` adapter type"
)]

/// A server handler for the Parent protocol.
///
/// See [`Parent`] for more details.
pub trait ParentLocalServerHandler<
    #[cfg(target_os = "fuchsia")] ___T: ::fidl_next::Transport = ::fidl_next::fuchsia::zx::Channel,
    #[cfg(not(target_os = "fuchsia"))] ___T: ::fidl_next::Transport,
>
{
    fn get_child(
        &mut self,

        responder: ::fidl_next::Responder<parent::GetChild, ___T>,
    ) -> impl ::core::future::Future<Output = ()>;

    fn get_child_request(
        &mut self,

        responder: ::fidl_next::Responder<parent::GetChildRequest, ___T>,
    ) -> impl ::core::future::Future<Output = ()>;

    fn take_child(
        &mut self,

        request: ::fidl_next::Request<parent::TakeChild, ___T>,
    ) -> impl ::core::future::Future<Output = ()>;

    fn take_child_request(
        &mut self,

        request: ::fidl_next::Request<parent::TakeChildRequest, ___T>,
    ) -> impl ::core::future::Future<Output = ()>;
}

impl<___H, ___T> ::fidl_next::DispatchLocalServerMessage<___H, ___T> for Parent
where
    ___H: ParentLocalServerHandler<___T>,
    ___T: ::fidl_next::Transport,
    for<'de> crate::wire::ParentTakeChildRequest: ::fidl_next::Decode<
            <<___T as ::fidl_next::Transport>::RecvBuffer as ::fidl_next::AsDecoder<'de>>::Decoder,
            Constraint = (),
        >,
    for<'de> crate::wire::ParentTakeChildRequestRequest: ::fidl_next::Decode<
            <<___T as ::fidl_next::Transport>::RecvBuffer as ::fidl_next::AsDecoder<'de>>::Decoder,
            Constraint = (),
        >,
{
    async fn on_one_way(
        handler: &mut ___H,
        ordinal: u64,
        flexibility: ::fidl_next::protocol::Flexibility,
        body: ::fidl_next::Body<___T>,
    ) -> ::core::result::Result<
        (),
        ::fidl_next::ProtocolError<<___T as ::fidl_next::Transport>::Error>,
    > {
        match ordinal {
            4470101341872267920 => match ::fidl_next::AsDecoderExt::into_decoded(body) {
                Ok(decoded) => {
                    handler.take_child(::fidl_next::Request::from_decoded(decoded)).await;
                    Ok(())
                }
                Err(error) => Err(::fidl_next::ProtocolError::InvalidMessage {
                    ordinal: 4470101341872267920,
                    error,
                }),
            },

            2333981071306416007 => match ::fidl_next::AsDecoderExt::into_decoded(body) {
                Ok(decoded) => {
                    handler.take_child_request(::fidl_next::Request::from_decoded(decoded)).await;
                    Ok(())
                }
                Err(error) => Err(::fidl_next::ProtocolError::InvalidMessage {
                    ordinal: 2333981071306416007,
                    error,
                }),
            },

            ordinal => Err(::fidl_next::ProtocolError::UnknownOrdinal(ordinal)),
        }
    }

    async fn on_two_way(
        handler: &mut ___H,
        ordinal: u64,
        flexibility: ::fidl_next::protocol::Flexibility,
        body: ::fidl_next::Body<___T>,
        responder: ::fidl_next::protocol::Responder<___T>,
    ) -> ::core::result::Result<
        (),
        ::fidl_next::ProtocolError<<___T as ::fidl_next::Transport>::Error>,
    > {
        match ordinal {
            881818649151440699 => {
                let responder = ::fidl_next::Responder::from_untyped(responder);

                handler.get_child(responder).await;
                Ok(())
            }

            1096855814967598201 => {
                let responder = ::fidl_next::Responder::from_untyped(responder);

                handler.get_child_request(responder).await;
                Ok(())
            }

            ordinal => Err(::fidl_next::ProtocolError::UnknownOrdinal(ordinal)),
        }
    }
}

/// A client handler for the Parent protocol.
///
/// See [`Parent`] for more details.
pub trait ParentClientHandler<
    #[cfg(target_os = "fuchsia")] ___T: ::fidl_next::Transport = ::fidl_next::fuchsia::zx::Channel,
    #[cfg(not(target_os = "fuchsia"))] ___T: ::fidl_next::Transport,
>
{
}

impl<___H, ___T> ::fidl_next::DispatchClientMessage<___H, ___T> for Parent
where
    ___H: ParentClientHandler<___T> + ::core::marker::Send,
    ___T: ::fidl_next::Transport,
{
    async fn on_event(
        handler: &mut ___H,
        ordinal: u64,
        flexibility: ::fidl_next::protocol::Flexibility,
        body: ::fidl_next::Body<___T>,
    ) -> ::core::result::Result<(), ::fidl_next::ProtocolError<___T::Error>> {
        match ordinal {
            ordinal => Err(::fidl_next::ProtocolError::UnknownOrdinal(ordinal)),
        }
    }
}

/// A server handler for the Parent protocol.
///
/// See [`Parent`] for more details.
pub trait ParentServerHandler<
    #[cfg(target_os = "fuchsia")] ___T: ::fidl_next::Transport = ::fidl_next::fuchsia::zx::Channel,
    #[cfg(not(target_os = "fuchsia"))] ___T: ::fidl_next::Transport,
>
{
    fn get_child(
        &mut self,

        responder: ::fidl_next::Responder<parent::GetChild, ___T>,
    ) -> impl ::core::future::Future<Output = ()> + ::core::marker::Send;

    fn get_child_request(
        &mut self,

        responder: ::fidl_next::Responder<parent::GetChildRequest, ___T>,
    ) -> impl ::core::future::Future<Output = ()> + ::core::marker::Send;

    fn take_child(
        &mut self,

        request: ::fidl_next::Request<parent::TakeChild, ___T>,
    ) -> impl ::core::future::Future<Output = ()> + ::core::marker::Send;

    fn take_child_request(
        &mut self,

        request: ::fidl_next::Request<parent::TakeChildRequest, ___T>,
    ) -> impl ::core::future::Future<Output = ()> + ::core::marker::Send;
}

impl<___H, ___T> ::fidl_next::DispatchServerMessage<___H, ___T> for Parent
where
    ___H: ParentServerHandler<___T> + ::core::marker::Send,
    ___T: ::fidl_next::Transport,
    for<'de> crate::wire::ParentTakeChildRequest: ::fidl_next::Decode<
            <<___T as ::fidl_next::Transport>::RecvBuffer as ::fidl_next::AsDecoder<'de>>::Decoder,
            Constraint = (),
        >,
    for<'de> crate::wire::ParentTakeChildRequestRequest: ::fidl_next::Decode<
            <<___T as ::fidl_next::Transport>::RecvBuffer as ::fidl_next::AsDecoder<'de>>::Decoder,
            Constraint = (),
        >,
{
    async fn on_one_way(
        handler: &mut ___H,
        ordinal: u64,
        flexibility: ::fidl_next::protocol::Flexibility,
        body: ::fidl_next::Body<___T>,
    ) -> ::core::result::Result<
        (),
        ::fidl_next::ProtocolError<<___T as ::fidl_next::Transport>::Error>,
    > {
        match ordinal {
            4470101341872267920 => match ::fidl_next::AsDecoderExt::into_decoded(body) {
                Ok(decoded) => {
                    handler.take_child(::fidl_next::Request::from_decoded(decoded)).await;
                    Ok(())
                }
                Err(error) => Err(::fidl_next::ProtocolError::InvalidMessage {
                    ordinal: 4470101341872267920,
                    error,
                }),
            },

            2333981071306416007 => match ::fidl_next::AsDecoderExt::into_decoded(body) {
                Ok(decoded) => {
                    handler.take_child_request(::fidl_next::Request::from_decoded(decoded)).await;
                    Ok(())
                }
                Err(error) => Err(::fidl_next::ProtocolError::InvalidMessage {
                    ordinal: 2333981071306416007,
                    error,
                }),
            },

            ordinal => Err(::fidl_next::ProtocolError::UnknownOrdinal(ordinal)),
        }
    }

    async fn on_two_way(
        handler: &mut ___H,
        ordinal: u64,
        flexibility: ::fidl_next::protocol::Flexibility,
        body: ::fidl_next::Body<___T>,
        responder: ::fidl_next::protocol::Responder<___T>,
    ) -> ::core::result::Result<
        (),
        ::fidl_next::ProtocolError<<___T as ::fidl_next::Transport>::Error>,
    > {
        match ordinal {
            881818649151440699 => {
                let responder = ::fidl_next::Responder::from_untyped(responder);

                handler.get_child(responder).await;
                Ok(())
            }

            1096855814967598201 => {
                let responder = ::fidl_next::Responder::from_untyped(responder);

                handler.get_child_request(responder).await;
                Ok(())
            }

            ordinal => Err(::fidl_next::ProtocolError::UnknownOrdinal(ordinal)),
        }
    }
}

impl<___T> ParentClientHandler<___T> for ::fidl_next::IgnoreEvents where ___T: ::fidl_next::Transport
{}

impl<___H, ___T> ParentLocalClientHandler<___T> for ::fidl_next::Local<___H>
where
    ___H: ParentClientHandler<___T>,
    ___T: ::fidl_next::Transport,
{
}

impl<___H, ___T> ParentLocalServerHandler<___T> for ::fidl_next::Local<___H>
where
    ___H: ParentServerHandler<___T>,
    ___T: ::fidl_next::Transport,
{
    async fn get_child(&mut self, responder: ::fidl_next::Responder<parent::GetChild, ___T>) {
        ___H::get_child(&mut self.0, responder).await
    }

    async fn get_child_request(
        &mut self,

        responder: ::fidl_next::Responder<parent::GetChildRequest, ___T>,
    ) {
        ___H::get_child_request(&mut self.0, responder).await
    }

    async fn take_child(&mut self, request: ::fidl_next::Request<parent::TakeChild, ___T>) {
        ___H::take_child(&mut self.0, request).await
    }

    async fn take_child_request(
        &mut self,

        request: ::fidl_next::Request<parent::TakeChildRequest, ___T>,
    ) {
        ___H::take_child_request(&mut self.0, request).await
    }
}

pub use fidl_next_common_test_protocolrequest::*;
