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

// fidl_experiment = output_index_json

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

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

namespace fidl {
namespace internal {

#ifdef __Fuchsia__

::test_driverhandle::ClientEndWrapper WireNaturalConversionTraits<::test_driverhandle::wire::ClientEndWrapper, ::test_driverhandle::ClientEndWrapper>::ToNatural(::test_driverhandle::wire::ClientEndWrapper src) {
  return ::test_driverhandle::ClientEndWrapper(WireNaturalConversionTraits<::fdf::ClientEnd<::test_driverhandle::DriverProtocol>, ::fdf::ClientEnd<::test_driverhandle::DriverProtocol>>::ToNatural(std::move(src.value)));
}
::test_driverhandle::wire::ClientEndWrapper WireNaturalConversionTraits<::test_driverhandle::wire::ClientEndWrapper, ::test_driverhandle::ClientEndWrapper>::ToWire(fidl::AnyArena& arena, ::test_driverhandle::ClientEndWrapper src) {
  return ::test_driverhandle::wire::ClientEndWrapper{
      .value = WireNaturalConversionTraits<::fdf::ClientEnd<::test_driverhandle::DriverProtocol>, ::fdf::ClientEnd<::test_driverhandle::DriverProtocol>>::ToWire(arena, std::move(src.value())),
  };
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

::test_driverhandle::ServerEndWrapper WireNaturalConversionTraits<::test_driverhandle::wire::ServerEndWrapper, ::test_driverhandle::ServerEndWrapper>::ToNatural(::test_driverhandle::wire::ServerEndWrapper src) {
  return ::test_driverhandle::ServerEndWrapper(WireNaturalConversionTraits<::fdf::ServerEnd<::test_driverhandle::DriverProtocol>, ::fdf::ServerEnd<::test_driverhandle::DriverProtocol>>::ToNatural(std::move(src.value)));
}
::test_driverhandle::wire::ServerEndWrapper WireNaturalConversionTraits<::test_driverhandle::wire::ServerEndWrapper, ::test_driverhandle::ServerEndWrapper>::ToWire(fidl::AnyArena& arena, ::test_driverhandle::ServerEndWrapper src) {
  return ::test_driverhandle::wire::ServerEndWrapper{
      .value = WireNaturalConversionTraits<::fdf::ServerEnd<::test_driverhandle::DriverProtocol>, ::fdf::ServerEnd<::test_driverhandle::DriverProtocol>>::ToWire(arena, std::move(src.value())),
  };
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

::test_driverhandle::HandlesInProtocolSendHandlesRequest WireNaturalConversionTraits<::test_driverhandle::wire::HandlesInProtocolSendHandlesRequest, ::test_driverhandle::HandlesInProtocolSendHandlesRequest>::ToNatural(::test_driverhandle::wire::HandlesInProtocolSendHandlesRequest src) {
  return ::test_driverhandle::HandlesInProtocolSendHandlesRequest(WireNaturalConversionTraits<::test_driverhandle::wire::T, ::test_driverhandle::T>::ToNatural(std::move(src.t)));
}
::test_driverhandle::wire::HandlesInProtocolSendHandlesRequest WireNaturalConversionTraits<::test_driverhandle::wire::HandlesInProtocolSendHandlesRequest, ::test_driverhandle::HandlesInProtocolSendHandlesRequest>::ToWire(fidl::AnyArena& arena, ::test_driverhandle::HandlesInProtocolSendHandlesRequest src) {
  return ::test_driverhandle::wire::HandlesInProtocolSendHandlesRequest{
      .t = WireNaturalConversionTraits<::test_driverhandle::wire::T, ::test_driverhandle::T>::ToWire(arena, std::move(src.t())),
  };
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

::test_driverhandle::T WireNaturalConversionTraits<::test_driverhandle::wire::T, ::test_driverhandle::T>::ToNatural(::test_driverhandle::wire::T src) {
  ::test_driverhandle::T dst;
  if (src.has_zircon_handle()) {
    dst.zircon_handle() =
        WireNaturalConversionTraits<::zx::event, ::zx::event>::ToNatural(std::move(src.zircon_handle()));
  }
  if (src.has_fdf_handle()) {
    dst.fdf_handle() =
        WireNaturalConversionTraits<::fdf::ClientEnd<::test_driverhandle::DriverProtocol>, ::fdf::ClientEnd<::test_driverhandle::DriverProtocol>>::ToNatural(std::move(src.fdf_handle()));
  }

  return dst;
}
::test_driverhandle::wire::T WireNaturalConversionTraits<::test_driverhandle::wire::T, ::test_driverhandle::T>::ToWire(fidl::AnyArena& arena, ::test_driverhandle::T src) {
  auto builder = ::test_driverhandle::wire::T::Builder(arena);
  if (src.zircon_handle().has_value()) {
    builder.zircon_handle(
        WireNaturalConversionTraits<::zx::event, ::zx::event>::ToWire(arena, std::move(src.zircon_handle().value())));
  }
  if (src.fdf_handle().has_value()) {
    builder.fdf_handle(
        WireNaturalConversionTraits<::fdf::ClientEnd<::test_driverhandle::DriverProtocol>, ::fdf::ClientEnd<::test_driverhandle::DriverProtocol>>::ToWire(arena, std::move(src.fdf_handle().value())));
  }
  return builder.Build();
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

#endif  // __Fuchsia__
#pragma clang diagnostic pop

}  // namespace internal
}  // namespace fidl
