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

// fidl_experiment = output_index_json

#include <fidl/test.doccomments/cpp/type_conversions.h>

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wshadow"

namespace fidl {
namespace internal {

::test_doccomments::Struct WireNaturalConversionTraits<::test_doccomments::wire::Struct, ::test_doccomments::Struct>::ToNatural(::test_doccomments::wire::Struct src) {
  return ::test_doccomments::Struct(WireNaturalConversionTraits<int32_t, int32_t>::ToNatural(std::move(src.field)));
}
::test_doccomments::wire::Struct WireNaturalConversionTraits<::test_doccomments::wire::Struct, ::test_doccomments::Struct>::ToWire(fidl::AnyArena& arena, ::test_doccomments::Struct src) {
  return ::test_doccomments::wire::Struct{
      .field = WireNaturalConversionTraits<int32_t, int32_t>::ToWire(arena, std::move(src.field())),
  };
}

::test_doccomments::Table WireNaturalConversionTraits<::test_doccomments::wire::Table, ::test_doccomments::Table>::ToNatural(::test_doccomments::wire::Table src) {
  ::test_doccomments::Table dst;
  if (src.has_Field()) {
    dst.field() =
        WireNaturalConversionTraits<int32_t, int32_t>::ToNatural(std::move(src.field()));
  }

  return dst;
}
::test_doccomments::wire::Table WireNaturalConversionTraits<::test_doccomments::wire::Table, ::test_doccomments::Table>::ToWire(fidl::AnyArena& arena, ::test_doccomments::Table src) {
  auto builder = ::test_doccomments::wire::Table::Builder(arena);
  if (src.field().has_value()) {
    builder.field(
        WireNaturalConversionTraits<int32_t, int32_t>::ToWire(arena, std::move(src.field().value())));
  }
  return builder.Build();
}

::test_doccomments::StrictUnion WireNaturalConversionTraits<::test_doccomments::wire::StrictUnion, ::test_doccomments::StrictUnion>::ToNatural(::test_doccomments::wire::StrictUnion src) {
  switch (src.Which()) {
    case ::test_doccomments::wire::StrictUnion::Tag::kField:
      return ::test_doccomments::StrictUnion::WithField(
          WireNaturalConversionTraits<int32_t, int32_t>::ToNatural(std::move(src.field())));
    default:
      ZX_PANIC("unknown union tag in strict union");
  }
}
::test_doccomments::wire::StrictUnion WireNaturalConversionTraits<::test_doccomments::wire::StrictUnion, ::test_doccomments::StrictUnion>::ToWire(fidl::AnyArena& arena, ::test_doccomments::StrictUnion src) {
  switch (src.Which()) {
    case ::test_doccomments::StrictUnion::Tag::kField:
      return ::test_doccomments::wire::StrictUnion::WithField(
          WireNaturalConversionTraits<int32_t, int32_t>::ToWire(arena, std::move(src.field().value())));
  }
}

::test_doccomments::FlexibleUnion WireNaturalConversionTraits<::test_doccomments::wire::FlexibleUnion, ::test_doccomments::FlexibleUnion>::ToNatural(::test_doccomments::wire::FlexibleUnion src) {
  switch (src.Which()) {
    case ::test_doccomments::wire::FlexibleUnion::Tag::kField:
      return ::test_doccomments::FlexibleUnion::WithField(
          WireNaturalConversionTraits<int32_t, int32_t>::ToNatural(std::move(src.field())));
    default:
      return ::test_doccomments::FlexibleUnion(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{});
  }
}
::test_doccomments::wire::FlexibleUnion WireNaturalConversionTraits<::test_doccomments::wire::FlexibleUnion, ::test_doccomments::FlexibleUnion>::ToWire(fidl::AnyArena& arena, ::test_doccomments::FlexibleUnion src) {
  switch (src.Which()) {
    case ::test_doccomments::FlexibleUnion::Tag::kField:
      return ::test_doccomments::wire::FlexibleUnion::WithField(
          WireNaturalConversionTraits<int32_t, int32_t>::ToWire(arena, std::move(src.field().value())));
    default:
      return ::test_doccomments::wire::FlexibleUnion();
  }
}

#ifdef __Fuchsia__

#endif  // __Fuchsia__
#pragma clang diagnostic pop

}  // namespace internal
}  // namespace fidl
