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

#pragma once

#include <fidl/test.driverhandle/cpp/natural_types.h>
#include <lib/fidl/cpp/hlcpp_conversion.h>
#include <lib/fidl/llcpp/internal/transport_channel.h>
#include <test/driverhandle/cpp/fidl.h>

namespace fidl {
namespace internal {

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::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::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::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::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::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::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::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;
}

}  // namespace internal
}  // namespace fidl
