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

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

namespace fidl {
namespace internal {

::test_error::ExampleFooResponse WireNaturalConversionTraits<
    ::test_error::wire::ExampleFooResponse, ::test_error::ExampleFooResponse>::
    ToNatural(::test_error::wire::ExampleFooResponse src) {
  return ::test_error::ExampleFooResponse(
      WireNaturalConversionTraits<int64_t, int64_t>::ToNatural(
          std::move(src.y)));
}
::test_error::wire::ExampleFooResponse WireNaturalConversionTraits<
    ::test_error::wire::ExampleFooResponse, ::test_error::ExampleFooResponse>::
    ToWire(fidl::AnyArena& arena, ::test_error::ExampleFooResponse src) {
  return ::test_error::wire::ExampleFooResponse{
      .y = WireNaturalConversionTraits<int64_t, int64_t>::ToWire(
          arena, std::move(src.y())),
  };
}

::test_error::ExampleFooTopResponse
WireNaturalConversionTraits<::test_error::wire::ExampleFooTopResponse,
                            ::test_error::ExampleFooTopResponse>::
    ToNatural(::test_error::wire::ExampleFooTopResponse src) {
  return ::test_error::ExampleFooTopResponse(
      WireNaturalConversionTraits<
          ::test_error::wire::ExampleFooResult,
          ::test_error::ExampleFooResult>::ToNatural(std::move(src.result)));
}
::test_error::wire::ExampleFooTopResponse
WireNaturalConversionTraits<::test_error::wire::ExampleFooTopResponse,
                            ::test_error::ExampleFooTopResponse>::
    ToWire(fidl::AnyArena& arena, ::test_error::ExampleFooTopResponse src) {
  return ::test_error::wire::ExampleFooTopResponse{
      .result = WireNaturalConversionTraits<
          ::test_error::wire::ExampleFooResult,
          ::test_error::ExampleFooResult>::ToWire(arena,
                                                  std::move(src.result())),
  };
}

::test_error::ExampleFooRequest WireNaturalConversionTraits<
    ::test_error::wire::ExampleFooRequest, ::test_error::ExampleFooRequest>::
    ToNatural(::test_error::wire::ExampleFooRequest src) {
  return ::test_error::ExampleFooRequest(
      WireNaturalConversionTraits<::fidl::StringView, ::std::string>::ToNatural(
          std::move(src.s)));
}
::test_error::wire::ExampleFooRequest WireNaturalConversionTraits<
    ::test_error::wire::ExampleFooRequest, ::test_error::ExampleFooRequest>::
    ToWire(fidl::AnyArena& arena, ::test_error::ExampleFooRequest src) {
  return ::test_error::wire::ExampleFooRequest{
      .s = WireNaturalConversionTraits<
          ::fidl::StringView, ::std::string>::ToWire(arena, std::move(src.s())),
  };
}

::test_error::ExampleFooResult WireNaturalConversionTraits<
    ::test_error::wire::ExampleFooResult, ::test_error::ExampleFooResult>::
    ToNatural(::test_error::wire::ExampleFooResult src) {
  switch (src.Which()) {
    case ::test_error::wire::ExampleFooResult::Tag::kResponse:
      return ::test_error::ExampleFooResult::WithResponse(
          WireNaturalConversionTraits<::test_error::wire::ExampleFooResponse,
                                      ::test_error::ExampleFooResponse>::
              ToNatural(std::move(src.response())));
    case ::test_error::wire::ExampleFooResult::Tag::kErr:
      return ::test_error::ExampleFooResult::WithErr(
          WireNaturalConversionTraits<uint32_t, uint32_t>::ToNatural(
              std::move(src.err())));
    default:
      ZX_PANIC("unknown union tag in strict union");
  }
}
::test_error::wire::ExampleFooResult WireNaturalConversionTraits<
    ::test_error::wire::ExampleFooResult, ::test_error::ExampleFooResult>::
    ToWire(fidl::AnyArena& arena, ::test_error::ExampleFooResult src) {
  switch (src.Which()) {
    case ::test_error::ExampleFooResult::Tag::kResponse:
      return ::test_error::wire::ExampleFooResult::WithResponse(
          arena,
          WireNaturalConversionTraits<::test_error::wire::ExampleFooResponse,
                                      ::test_error::ExampleFooResponse>::
              ToWire(arena, std::move(src.response().value())));
    case ::test_error::ExampleFooResult::Tag::kErr:
      return ::test_error::wire::ExampleFooResult::WithErr(
          WireNaturalConversionTraits<uint32_t, uint32_t>::ToWire(
              arena, std::move(src.err().value())));
  }
}

std::unique_ptr<::test_error::ExampleFooResult>
WireNaturalConversionTraits<::test_error::wire::ExampleFooResult,
                            std::unique_ptr<::test_error::ExampleFooResult>>::
    ToNatural(::test_error::wire::ExampleFooResult src) {
  if (src.has_invalid_tag()) {
    return nullptr;
  }
  return std::make_unique<::test_error::ExampleFooResult>(
      WireNaturalConversionTraits<
          ::test_error::wire::ExampleFooResult,
          ::test_error::ExampleFooResult>::ToNatural(std::move(src)));
}
::test_error::wire::ExampleFooResult
WireNaturalConversionTraits<::test_error::wire::ExampleFooResult,
                            std::unique_ptr<::test_error::ExampleFooResult>>::
    ToWire(fidl::AnyArena& arena,
           std::unique_ptr<::test_error::ExampleFooResult> src) {
  if (!src) {
    return ::test_error::wire::ExampleFooResult();
  }
  return WireNaturalConversionTraits<
      ::test_error::wire::ExampleFooResult,
      ::test_error::ExampleFooResult>::ToWire(arena, std::move(*src));
}

#ifdef __Fuchsia__

::fidl::Request<::test_error::Example::Foo>
WireNaturalConversionTraits<::fidl::WireRequest<::test_error::Example::Foo>,
                            ::fidl::Request<::test_error::Example::Foo>>::
    ToNatural(::fidl::WireRequest<::test_error::Example::Foo> src) {
  return ::fidl::Request<::test_error::Example::Foo>(
      WireNaturalConversionTraits<
          ::test_error::wire::ExampleFooRequest,
          ::test_error::ExampleFooRequest>::ToNatural(std::move(src)));
}
::fidl::WireRequest<::test_error::Example::Foo>
WireNaturalConversionTraits<::fidl::WireRequest<::test_error::Example::Foo>,
                            ::fidl::Request<::test_error::Example::Foo>>::
    ToWire(fidl::AnyArena& arena,
           ::fidl::Request<::test_error::Example::Foo> src) {
  return ::fidl::WireRequest<::test_error::Example::Foo>(
      WireNaturalConversionTraits<
          ::test_error::wire::ExampleFooRequest,
          ::test_error::ExampleFooRequest>::ToWire(arena, std::move(src)));
}

::fidl::Response<::test_error::Example::Foo>
WireNaturalConversionTraits<::fidl::WireResponse<::test_error::Example::Foo>,
                            ::fidl::Response<::test_error::Example::Foo>>::
    ToNatural(::fidl::WireResponse<::test_error::Example::Foo> src) {
  return ::fidl::Response<::test_error::Example::Foo>(
      WireNaturalConversionTraits<
          ::test_error::wire::ExampleFooTopResponse,
          ::fitx::result<uint32_t, ::test_error::ExampleFooResponse>>::
          ToNatural(std::move(src)));
}
::fidl::WireResponse<::test_error::Example::Foo>
WireNaturalConversionTraits<::fidl::WireResponse<::test_error::Example::Foo>,
                            ::fidl::Response<::test_error::Example::Foo>>::
    ToWire(fidl::AnyArena& arena,
           ::fidl::Response<::test_error::Example::Foo> src) {
  return ::fidl::WireResponse<::test_error::Example::Foo>(
      WireNaturalConversionTraits<
          ::test_error::wire::ExampleFooTopResponse,
          ::fitx::result<uint32_t, ::test_error::ExampleFooResponse>>::
          ToWire(arena, std::move(src)));
}
#endif  // __Fuchsia__
}  // namespace internal
}  // namespace fidl
