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

// fidl_experiment = output_index_json

#pragma once

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

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

namespace fidl {
namespace internal {

template <>
struct NaturalToHLCPPTraits<::test_driverhandle::ClientEndWrapper> {
  using HLCPPType = ::test::driverhandle::ClientEndWrapper;
  static inline ::test::driverhandle::ClientEndWrapper Convert(::test_driverhandle::ClientEndWrapper&&);
};
template <>
struct HLCPPToNaturalTraits<::test::driverhandle::ClientEndWrapper> {
  using NaturalType = ::test_driverhandle::ClientEndWrapper;
  static inline ::test_driverhandle::ClientEndWrapper Convert(::test::driverhandle::ClientEndWrapper&&);
};
template <>
struct NaturalToHLCPPTraits<::test_driverhandle::ServerEndWrapper> {
  using HLCPPType = ::test::driverhandle::ServerEndWrapper;
  static inline ::test::driverhandle::ServerEndWrapper Convert(::test_driverhandle::ServerEndWrapper&&);
};
template <>
struct HLCPPToNaturalTraits<::test::driverhandle::ServerEndWrapper> {
  using NaturalType = ::test_driverhandle::ServerEndWrapper;
  static inline ::test_driverhandle::ServerEndWrapper Convert(::test::driverhandle::ServerEndWrapper&&);
};
template <>
struct NaturalToHLCPPTraits<::test_driverhandle::HandlesInProtocolSendHandlesRequest> {
  using HLCPPType = ::test::driverhandle::HandlesInProtocolSendHandlesRequest;
  static inline ::test::driverhandle::HandlesInProtocolSendHandlesRequest Convert(::test_driverhandle::HandlesInProtocolSendHandlesRequest&&);
};
template <>
struct HLCPPToNaturalTraits<::test::driverhandle::HandlesInProtocolSendHandlesRequest> {
  using NaturalType = ::test_driverhandle::HandlesInProtocolSendHandlesRequest;
  static inline ::test_driverhandle::HandlesInProtocolSendHandlesRequest Convert(::test::driverhandle::HandlesInProtocolSendHandlesRequest&&);
};
template <>
struct NaturalToHLCPPTraits<::test_driverhandle::T> {
  using HLCPPType = ::test::driverhandle::T;
  static inline ::test::driverhandle::T Convert(::test_driverhandle::T&&);
};
template <>
struct HLCPPToNaturalTraits<::test::driverhandle::T> {
  using NaturalType = ::test_driverhandle::T;
  static inline ::test_driverhandle::T Convert(::test::driverhandle::T&&);
};

::test::driverhandle::ClientEndWrapper NaturalToHLCPPTraits<::test_driverhandle::ClientEndWrapper>::Convert(::test_driverhandle::ClientEndWrapper&& value) {
  ::test::driverhandle::ClientEndWrapper hlcpp;
  hlcpp.value = ::fidl::NaturalToHLCPP(std::move(value.value()));
  return hlcpp;
}

::test_driverhandle::ClientEndWrapper HLCPPToNaturalTraits<::test::driverhandle::ClientEndWrapper>::Convert(::test::driverhandle::ClientEndWrapper&& value) {
  return ::test_driverhandle::ClientEndWrapper{{
      .value = ::fidl::HLCPPToNatural(std::move(value.value)),
  }};
}
::test::driverhandle::ServerEndWrapper NaturalToHLCPPTraits<::test_driverhandle::ServerEndWrapper>::Convert(::test_driverhandle::ServerEndWrapper&& value) {
  ::test::driverhandle::ServerEndWrapper hlcpp;
  hlcpp.value = ::fidl::NaturalToHLCPP(std::move(value.value()));
  return hlcpp;
}

::test_driverhandle::ServerEndWrapper HLCPPToNaturalTraits<::test::driverhandle::ServerEndWrapper>::Convert(::test::driverhandle::ServerEndWrapper&& value) {
  return ::test_driverhandle::ServerEndWrapper{{
      .value = ::fidl::HLCPPToNatural(std::move(value.value)),
  }};
}
::test::driverhandle::HandlesInProtocolSendHandlesRequest NaturalToHLCPPTraits<::test_driverhandle::HandlesInProtocolSendHandlesRequest>::Convert(::test_driverhandle::HandlesInProtocolSendHandlesRequest&& value) {
  ::test::driverhandle::HandlesInProtocolSendHandlesRequest hlcpp;
  hlcpp.t = ::fidl::NaturalToHLCPP(std::move(value.t()));
  return hlcpp;
}

::test_driverhandle::HandlesInProtocolSendHandlesRequest HLCPPToNaturalTraits<::test::driverhandle::HandlesInProtocolSendHandlesRequest>::Convert(::test::driverhandle::HandlesInProtocolSendHandlesRequest&& value) {
  return ::test_driverhandle::HandlesInProtocolSendHandlesRequest{{
      .t = ::fidl::HLCPPToNatural(std::move(value.t)),
  }};
}
::test::driverhandle::T NaturalToHLCPPTraits<::test_driverhandle::T>::Convert(::test_driverhandle::T&& value) {
  ::test::driverhandle::T hlcpp;
  if (value.zircon_handle().has_value()) {
    hlcpp.set_zircon_handle(::fidl::NaturalToHLCPP(std::move(value.zircon_handle().value())));
  }
  if (value.fdf_handle().has_value()) {
    hlcpp.set_fdf_handle(::fidl::NaturalToHLCPP(std::move(value.fdf_handle().value())));
  }
  return hlcpp;
}

::test_driverhandle::T HLCPPToNaturalTraits<::test::driverhandle::T>::Convert(::test::driverhandle::T&& value) {
  ::test_driverhandle::T natural;
  if (value.has_zircon_handle()) {
    natural.zircon_handle() = ::fidl::HLCPPToNatural(std::move(*value.mutable_zircon_handle()));
  }
  if (value.has_fdf_handle()) {
    natural.fdf_handle() = ::fidl::HLCPPToNatural(std::move(*value.mutable_fdf_handle()));
  }
  return natural;
}

#pragma clang diagnostic pop

}  // namespace internal
}  // namespace fidl
