// automatically generated by the FlatBuffers compiler, do not modify
// @generated
extern crate alloc;

pub enum TableAOffset {}

#[derive(Copy, Clone, PartialEq)]
pub struct TableA<'a> {
    pub _tab: ::flatbuffers::Table<'a>,
}

impl<'a> ::flatbuffers::Follow<'a> for TableA<'a> {
    type Inner = TableA<'a>;

    #[inline]
    unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
        Self { _tab: unsafe { ::flatbuffers::Table::new(buf, loc) } }
    }
}

impl<'a> TableA<'a> {
    pub const VT_B: ::flatbuffers::VOffsetT = 4;

    pub const fn get_fully_qualified_name() -> &'static str {
        "TableA"
    }

    #[inline]
    pub unsafe fn init_from_table(table: ::flatbuffers::Table<'a>) -> Self {
        TableA { _tab: table }
    }

    #[allow(unused_mut)]
    pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: ::flatbuffers::Allocator + 'bldr>(
        _fbb: &'mut_bldr mut ::flatbuffers::FlatBufferBuilder<'bldr, A>,
        args: &'args TableAArgs<'args>
    ) -> ::flatbuffers::WIPOffset<TableA<'bldr>> {
        let mut builder = TableABuilder::new(_fbb);
        if let Some(x) = args.b { builder.add_b(x); }
        builder.finish()
    }

    pub fn unpack(&self) -> TableAT {
        let b = self.b().map(|x| {
            alloc::boxed::Box::new(x.unpack())
        });
        TableAT {
            b,
        }
    }

    #[inline]
    pub fn b(&self) -> Option<my_game::other_name_space::TableB<'a>> {
        // Safety:
        // Created from valid Table for this object
        // which contains a valid value in this slot
        unsafe { self._tab.get::<::flatbuffers::ForwardsUOffset<my_game::other_name_space::TableB>>(TableA::VT_B, None)}
    }
}

impl ::flatbuffers::Verifiable for TableA<'_> {
    #[inline]
    fn run_verifier(
        v: &mut ::flatbuffers::Verifier, pos: usize
    ) -> Result<(), ::flatbuffers::InvalidFlatbuffer> {
        v.visit_table(pos)?
            .visit_field::<::flatbuffers::ForwardsUOffset<my_game::other_name_space::TableB>>("b", Self::VT_B, false)?
            .finish();
        Ok(())
    }
}

pub struct TableAArgs<'a> {
    pub b: Option<::flatbuffers::WIPOffset<my_game::other_name_space::TableB<'a>>>,
}

impl<'a> Default for TableAArgs<'a> {
    #[inline]
    fn default() -> Self {
        TableAArgs {
            b: None,
        }
    }
}

pub struct TableABuilder<'a: 'b, 'b, A: ::flatbuffers::Allocator + 'a> {
    fbb_: &'b mut ::flatbuffers::FlatBufferBuilder<'a, A>,
    start_: ::flatbuffers::WIPOffset<::flatbuffers::TableUnfinishedWIPOffset>,
}

impl<'a: 'b, 'b, A: ::flatbuffers::Allocator + 'a> TableABuilder<'a, 'b, A> {
    #[inline]
    pub fn add_b(&mut self, b: ::flatbuffers::WIPOffset<my_game::other_name_space::TableB<'b >>) {
        self.fbb_.push_slot_always::<::flatbuffers::WIPOffset<my_game::other_name_space::TableB>>(TableA::VT_B, b);
    }

    #[inline]
    pub fn new(_fbb: &'b mut ::flatbuffers::FlatBufferBuilder<'a, A>) -> TableABuilder<'a, 'b, A> {
        let start = _fbb.start_table();
        TableABuilder {
            fbb_: _fbb,
            start_: start,
        }
    }

    #[inline]
    pub fn finish(self) -> ::flatbuffers::WIPOffset<TableA<'a>> {
        let o = self.fbb_.end_table(self.start_);
        ::flatbuffers::WIPOffset::new(o.value())
    }
}

impl ::core::fmt::Debug for TableA<'_> {
    fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
        let mut ds = f.debug_struct("TableA");
        ds.field("b", &self.b());
        ds.finish()
    }
}

#[non_exhaustive]
#[derive(Debug, Clone, PartialEq)]
pub struct TableAT {
    pub b: Option<alloc::boxed::Box<my_game::other_name_space::TableBT>>,
}

impl Default for TableAT {
    fn default() -> Self {
        Self {
            b: None,
        }
    }
}

impl TableAT {
    pub fn pack<'b, A: ::flatbuffers::Allocator + 'b>(
        &self,
        _fbb: &mut ::flatbuffers::FlatBufferBuilder<'b, A>
    ) -> ::flatbuffers::WIPOffset<TableA<'b>> {
        let b = self.b.as_ref().map(|x|{
            x.pack(_fbb)
        });
        TableA::create(_fbb, &TableAArgs{
            b,
        })
    }
}

#[allow(unused_imports, dead_code)]
pub mod my_game {
    extern crate alloc;

    #[allow(unused_imports, dead_code)]
    pub mod other_name_space {
        extern crate alloc;

        #[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")]
        pub const ENUM_MIN_FROM_INCLUDE: i64 = 0;

        #[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")]
        pub const ENUM_MAX_FROM_INCLUDE: i64 = 0;

        #[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")]
        #[allow(non_camel_case_types)]
        pub const ENUM_VALUES_FROM_INCLUDE: [FromInclude; 1] = [
            FromInclude::IncludeVal,
        ];

        #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
        #[repr(transparent)]
        pub struct FromInclude(pub i64);

        #[allow(non_upper_case_globals)]
        impl FromInclude {
            pub const IncludeVal: Self = Self(0);

            pub const ENUM_MIN: i64 = 0;
            pub const ENUM_MAX: i64 = 0;
            pub const ENUM_VALUES: &'static [Self] = &[
                Self::IncludeVal,
            ];

            /// Returns the variant's name or "" if unknown.
            pub fn variant_name(self) -> Option<&'static str> {
                match self {
                    Self::IncludeVal => Some("IncludeVal"),
                    _ => None,
                }
            }
        }

        impl ::core::fmt::Debug for FromInclude {
            fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
                if let Some(name) = self.variant_name() {
                    f.write_str(name)
                } else {
                    f.write_fmt(format_args!("<UNKNOWN {:?}>", self.0))
                }
            }
        }

        impl<'a> ::flatbuffers::Follow<'a> for FromInclude {
            type Inner = Self;

            #[inline]
            unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
                let b = unsafe { ::flatbuffers::read_scalar_at::<i64>(buf, loc) };
                Self(b)
            }
        }

        impl ::flatbuffers::Push for FromInclude {
            type Output = FromInclude;

            #[inline]
            unsafe fn push(&self, dst: &mut [u8], _written_len: usize) {
                unsafe { ::flatbuffers::emplace_scalar::<i64>(dst, self.0) };
            }
        }

        impl ::flatbuffers::EndianScalar for FromInclude {
            type Scalar = i64;

            #[inline]
            fn to_little_endian(self) -> i64 {
                self.0.to_le()
            }

            #[inline]
            #[allow(clippy::wrong_self_convention)]
            fn from_little_endian(v: i64) -> Self {
                let b = i64::from_le(v);
                Self(b)
            }
        }

        impl<'a> ::flatbuffers::Verifiable for FromInclude {
            #[inline]
            fn run_verifier(
                v: &mut ::flatbuffers::Verifier, pos: usize
            ) -> Result<(), ::flatbuffers::InvalidFlatbuffer> {
                i64::run_verifier(v, pos)
            }
        }

        impl ::flatbuffers::SimpleToVerifyInSlice for FromInclude {}

        // struct Unused, aligned to 4
        #[repr(transparent)]
        #[derive(Clone, Copy, PartialEq)]
        pub struct Unused(pub [u8; 4]);

        impl Default for Unused {
            fn default() -> Self {
                Self([0; 4])
            }
        }

        impl ::core::fmt::Debug for Unused {
            fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
                f.debug_struct("Unused")
                    .field("a", &self.a())
                    .finish()
            }
        }

        impl ::flatbuffers::SimpleToVerifyInSlice for Unused {}

        impl<'a> ::flatbuffers::Follow<'a> for Unused {
            type Inner = &'a Unused;

            #[inline]
            unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
                unsafe { <&'a Unused>::follow(buf, loc) }
            }
        }

        impl<'a> ::flatbuffers::Follow<'a> for &'a Unused {
            type Inner = &'a Unused;

            #[inline]
            unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
                unsafe { ::flatbuffers::follow_cast_ref::<Unused>(buf, loc) }
            }
        }

        impl<'b> ::flatbuffers::Push for Unused {
            type Output = Unused;

            #[inline]
            unsafe fn push(&self, dst: &mut [u8], _written_len: usize) {
                let src = unsafe { ::core::slice::from_raw_parts(self as *const Unused as *const u8, <Self as ::flatbuffers::Push>::size()) };
                dst.copy_from_slice(src);
            }

            #[inline]
            fn alignment() -> ::flatbuffers::PushAlignment {
                ::flatbuffers::PushAlignment::new(4)
            }
        }

        impl<'a> ::flatbuffers::Verifiable for Unused {
            #[inline]
            fn run_verifier(
                v: &mut ::flatbuffers::Verifier, pos: usize
            ) -> Result<(), ::flatbuffers::InvalidFlatbuffer> {
                v.in_buffer::<Self>(pos)
            }
        }

        impl<'a> Unused {
            #[allow(clippy::too_many_arguments)]
            pub fn new(
                a: i32,
            ) -> Self {
                let mut s = Self([0; 4]);
                s.set_a(a);
                s
            }

            pub const fn get_fully_qualified_name() -> &'static str {
                "MyGame.OtherNameSpace.Unused"
            }

            pub fn a(&self) -> i32 {
                let mut mem = ::core::mem::MaybeUninit::<<i32 as ::flatbuffers::EndianScalar>::Scalar>::uninit();
                // Safety:
                // Created from a valid Table for this object
                // Which contains a valid value in this slot
                ::flatbuffers::EndianScalar::from_little_endian(unsafe {
                    ::core::ptr::copy_nonoverlapping(
                        self.0[0..].as_ptr(),
                        mem.as_mut_ptr() as *mut u8,
                        ::core::mem::size_of::<<i32 as ::flatbuffers::EndianScalar>::Scalar>(),
                    );
                    mem.assume_init()
                })
            }

            pub fn set_a(&mut self, x: i32) {
                let x_le = ::flatbuffers::EndianScalar::to_little_endian(x);
                // Safety:
                // Created from a valid Table for this object
                // Which contains a valid value in this slot
                unsafe {
                    ::core::ptr::copy_nonoverlapping(
                        &x_le as *const _ as *const u8,
                        self.0[0..].as_mut_ptr(),
                        ::core::mem::size_of::<<i32 as ::flatbuffers::EndianScalar>::Scalar>(),
                    );
                }
            }

            pub fn unpack(&self) -> UnusedT {
                UnusedT {
                    a: self.a(),
                }
            }
        }

        #[derive(Debug, Clone, PartialEq)]
        pub struct UnusedT {
            pub a: i32,
        }
        impl Default for UnusedT {
            fn default() -> Self {
                Self {
                    a: 0,
                }
            }
        }

        impl UnusedT {
            pub fn pack(&self) -> Unused {
                Unused::new(
                    self.a,
                )
            }
        }

        pub enum TableBOffset {}

        #[derive(Copy, Clone, PartialEq)]
        pub struct TableB<'a> {
            pub _tab: ::flatbuffers::Table<'a>,
        }

        impl<'a> ::flatbuffers::Follow<'a> for TableB<'a> {
            type Inner = TableB<'a>;

            #[inline]
            unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
                Self { _tab: unsafe { ::flatbuffers::Table::new(buf, loc) } }
            }
        }

        impl<'a> TableB<'a> {
            pub const VT_A: ::flatbuffers::VOffsetT = 4;

            pub const fn get_fully_qualified_name() -> &'static str {
                "MyGame.OtherNameSpace.TableB"
            }

            #[inline]
            pub unsafe fn init_from_table(table: ::flatbuffers::Table<'a>) -> Self {
                TableB { _tab: table }
            }

            #[allow(unused_mut)]
            pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: ::flatbuffers::Allocator + 'bldr>(
                _fbb: &'mut_bldr mut ::flatbuffers::FlatBufferBuilder<'bldr, A>,
                args: &'args TableBArgs<'args>
            ) -> ::flatbuffers::WIPOffset<TableB<'bldr>> {
                let mut builder = TableBBuilder::new(_fbb);
                if let Some(x) = args.a { builder.add_a(x); }
                builder.finish()
            }

            pub fn unpack(&self) -> TableBT {
                let a = self.a().map(|x| {
                    alloc::boxed::Box::new(x.unpack())
                });
                TableBT {
                    a,
                }
            }

            #[inline]
            pub fn a(&self) -> Option<super::super::TableA<'a>> {
                // Safety:
                // Created from valid Table for this object
                // which contains a valid value in this slot
                unsafe { self._tab.get::<::flatbuffers::ForwardsUOffset<super::super::TableA>>(TableB::VT_A, None)}
            }
        }

        impl ::flatbuffers::Verifiable for TableB<'_> {
            #[inline]
            fn run_verifier(
                v: &mut ::flatbuffers::Verifier, pos: usize
            ) -> Result<(), ::flatbuffers::InvalidFlatbuffer> {
                v.visit_table(pos)?
                    .visit_field::<::flatbuffers::ForwardsUOffset<super::super::TableA>>("a", Self::VT_A, false)?
                    .finish();
                Ok(())
            }
        }

        pub struct TableBArgs<'a> {
            pub a: Option<::flatbuffers::WIPOffset<super::super::TableA<'a>>>,
        }

        impl<'a> Default for TableBArgs<'a> {
            #[inline]
            fn default() -> Self {
                TableBArgs {
                    a: None,
                }
            }
        }

        pub struct TableBBuilder<'a: 'b, 'b, A: ::flatbuffers::Allocator + 'a> {
            fbb_: &'b mut ::flatbuffers::FlatBufferBuilder<'a, A>,
            start_: ::flatbuffers::WIPOffset<::flatbuffers::TableUnfinishedWIPOffset>,
        }

        impl<'a: 'b, 'b, A: ::flatbuffers::Allocator + 'a> TableBBuilder<'a, 'b, A> {
            #[inline]
            pub fn add_a(&mut self, a: ::flatbuffers::WIPOffset<super::super::TableA<'b >>) {
                self.fbb_.push_slot_always::<::flatbuffers::WIPOffset<super::super::TableA>>(TableB::VT_A, a);
            }

            #[inline]
            pub fn new(_fbb: &'b mut ::flatbuffers::FlatBufferBuilder<'a, A>) -> TableBBuilder<'a, 'b, A> {
                let start = _fbb.start_table();
                TableBBuilder {
                    fbb_: _fbb,
                    start_: start,
                }
            }

            #[inline]
            pub fn finish(self) -> ::flatbuffers::WIPOffset<TableB<'a>> {
                let o = self.fbb_.end_table(self.start_);
                ::flatbuffers::WIPOffset::new(o.value())
            }
        }

        impl ::core::fmt::Debug for TableB<'_> {
            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
                let mut ds = f.debug_struct("TableB");
                ds.field("a", &self.a());
                ds.finish()
            }
        }

        #[non_exhaustive]
        #[derive(Debug, Clone, PartialEq)]
        pub struct TableBT {
            pub a: Option<alloc::boxed::Box<super::super::TableAT>>,
        }

        impl Default for TableBT {
            fn default() -> Self {
                Self {
                    a: None,
                }
            }
        }

        impl TableBT {
            pub fn pack<'b, A: ::flatbuffers::Allocator + 'b>(
                &self,
                _fbb: &mut ::flatbuffers::FlatBufferBuilder<'b, A>
            ) -> ::flatbuffers::WIPOffset<TableB<'b>> {
                let a = self.a.as_ref().map(|x|{
                    x.pack(_fbb)
                });
                TableB::create(_fbb, &TableBArgs{
                    a,
                })
            }
        }
    } // pub mod OtherNameSpace
} // pub mod MyGame
