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

// fidl_experiment = output_index_json

#pragma once

#include <fidl/test.error/cpp/natural_types.h>
#include <lib/fidl/cpp/hlcpp_conversion.h>
#include <lib/fidl/cpp/wire/service_handler.h>
#include <test/error/cpp/fidl.h>

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

namespace fidl {
namespace internal {

template <>
struct NaturalToHLCPPTraits<fidl::ClientEnd<::test_error::Example>> {
  using HLCPPType = fidl::InterfaceHandle<::test::error::Example>;
  static inline fidl::InterfaceHandle<::test::error::Example> Convert(fidl::ClientEnd<::test_error::Example>&& c) {
    return fidl::InterfaceHandle<::test::error::Example>(c.TakeChannel());
  }
};

template <>
struct NaturalToHLCPPTraits<fidl::ServerEnd<::test_error::Example>> {
  using HLCPPType = fidl::InterfaceRequest<::test::error::Example>;
  static inline fidl::InterfaceRequest<::test::error::Example> Convert(fidl::ServerEnd<::test_error::Example>&& c) {
    return fidl::InterfaceRequest<::test::error::Example>(c.TakeChannel());
  }
};

template <>
struct HLCPPToNaturalTraits<fidl::InterfaceHandle<::test::error::Example>> {
  using NaturalType = fidl::ClientEnd<::test_error::Example>;
  static inline fidl::ClientEnd<::test_error::Example> Convert(fidl::InterfaceHandle<::test::error::Example>&& c) {
    return fidl::ClientEnd<::test_error::Example>(c.TakeChannel());
  }
};

template <>
struct HLCPPToNaturalTraits<fidl::InterfaceRequest<::test::error::Example>> {
  using NaturalType = fidl::ServerEnd<::test_error::Example>;
  static inline fidl::ServerEnd<::test_error::Example> Convert(fidl::InterfaceRequest<::test::error::Example>&& c) {
    return fidl::ServerEnd<::test_error::Example>(c.TakeChannel());
  }
};

template <>
struct NaturalToHLCPPTraits<fidl::ProtocolHandler<::test_error::Example>> {
  using HLCPPType = fidl::InterfaceRequestHandler<::test::error::Example>;
  static inline fidl::InterfaceRequestHandler<::test::error::Example> Convert(fidl::ProtocolHandler<::test_error::Example>&& c) {
    return [c = std::move(c)](fidl::InterfaceRequest<::test::error::Example> r) {
      c(::fidl::HLCPPToNatural(r));
    };
  }
};

template <>
struct HLCPPToNaturalTraits<fidl::InterfaceRequestHandler<::test::error::Example>> {
  using NaturalType = fidl::ProtocolHandler<::test_error::Example>;
  static inline fidl::ProtocolHandler<::test_error::Example> Convert(fidl::InterfaceRequestHandler<::test::error::Example>&& c) {
    return [c = std::move(c)](fidl::ServerEnd<::test_error::Example> r) {
      c(::fidl::NaturalToHLCPP(r));
    };
  }
};

template <>
struct NaturalToHLCPPTraits<::test_error::ExampleFooRequest> {
  using HLCPPType = ::test::error::ExampleFooRequest;
  static inline ::test::error::ExampleFooRequest Convert(::test_error::ExampleFooRequest&&);
};
template <>
struct HLCPPToNaturalTraits<::test::error::ExampleFooRequest> {
  using NaturalType = ::test_error::ExampleFooRequest;
  static inline ::test_error::ExampleFooRequest Convert(::test::error::ExampleFooRequest&&);
};
template <>
struct NaturalToHLCPPTraits<::test_error::ExampleFooResponse> {
  using HLCPPType = ::test::error::Example_foo_Response;
  static inline ::test::error::Example_foo_Response Convert(::test_error::ExampleFooResponse&&);
};
template <>
struct HLCPPToNaturalTraits<::test::error::Example_foo_Response> {
  using NaturalType = ::test_error::ExampleFooResponse;
  static inline ::test_error::ExampleFooResponse Convert(::test::error::Example_foo_Response&&);
};
template <>
struct NaturalToHLCPPTraits<::test_error::ExampleFooResult> {
  using HLCPPType = ::test::error::Example_foo_Result;
  static inline ::test::error::Example_foo_Result Convert(::test_error::ExampleFooResult&&);
};
template <>
struct HLCPPToNaturalTraits<::test::error::Example_foo_Result> {
  using NaturalType = ::test_error::ExampleFooResult;
  static inline ::test_error::ExampleFooResult Convert(::test::error::Example_foo_Result&&);
};

::test::error::ExampleFooRequest NaturalToHLCPPTraits<::test_error::ExampleFooRequest>::Convert(::test_error::ExampleFooRequest&& value) {
  ::test::error::ExampleFooRequest hlcpp;
  hlcpp.s = ::fidl::NaturalToHLCPP(std::move(value.s()));
  return hlcpp;
}

::test_error::ExampleFooRequest HLCPPToNaturalTraits<::test::error::ExampleFooRequest>::Convert(::test::error::ExampleFooRequest&& value) {
  return ::test_error::ExampleFooRequest{{
      .s = ::fidl::HLCPPToNatural(std::move(value.s)),
  }};
}
::test::error::Example_foo_Response NaturalToHLCPPTraits<::test_error::ExampleFooResponse>::Convert(::test_error::ExampleFooResponse&& value) {
  ::test::error::Example_foo_Response hlcpp;
  hlcpp.y = ::fidl::NaturalToHLCPP(std::move(value.y()));
  return hlcpp;
}

::test_error::ExampleFooResponse HLCPPToNaturalTraits<::test::error::Example_foo_Response>::Convert(::test::error::Example_foo_Response&& value) {
  return ::test_error::ExampleFooResponse{{
      .y = ::fidl::HLCPPToNatural(std::move(value.y)),
  }};
}

::test::error::Example_foo_Result NaturalToHLCPPTraits<::test_error::ExampleFooResult>::Convert(::test_error::ExampleFooResult&& value) {
  ::test::error::Example_foo_Result hlcpp;
  switch (value.Which()) {
    case ::test_error::ExampleFooResult::Tag::kResponse:
      hlcpp.set_response(::fidl::NaturalToHLCPP(std::move(value.response().value())));
      break;
    case ::test_error::ExampleFooResult::Tag::kErr:
      hlcpp.set_err(::fidl::NaturalToHLCPP(std::move(value.err().value())));
      break;
    default:
      break;
  }
  return hlcpp;
}

::test_error::ExampleFooResult HLCPPToNaturalTraits<::test::error::Example_foo_Result>::Convert(::test::error::Example_foo_Result&& value) {
  using _NaturalUnion = ::test_error::ExampleFooResult;
  switch (value.Which()) {
    case ::test::error::Example_foo_Result::Tag::kResponse:
      return _NaturalUnion::WithResponse(
          ::fidl::HLCPPToNatural(std::move(value.response())));
    case ::test::error::Example_foo_Result::Tag::kErr:
      return _NaturalUnion::WithErr(
          ::fidl::HLCPPToNatural(std::move(value.err())));
    default:
      ZX_PANIC("Can't convert invalid strict union %s from HLCPP to Natural", "::test::error::Example_foo_Result");
  }
}

#pragma clang diagnostic pop

}  // namespace internal
}  // namespace fidl
