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

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

namespace fidl {
namespace internal {

#ifdef __Fuchsia__

::test_typealiases::ExampleOfUseOfAliases
WireNaturalConversionTraits<::test_typealiases::wire::ExampleOfUseOfAliases,
                            ::test_typealiases::ExampleOfUseOfAliases>::
    ToNatural(::test_typealiases::wire::ExampleOfUseOfAliases src) {
  return ::test_typealiases::ExampleOfUseOfAliases({
      .field_of_u32 =
          WireNaturalConversionTraits<uint32_t, uint32_t>::ToNatural(
              std::move(src.field_of_u32)),
      .field_of_vec_of_strings =
          WireNaturalConversionTraits<::fidl::VectorView<::fidl::StringView>,
                                      ::std::vector<::std::string>>::
              ToNatural(std::move(src.field_of_vec_of_strings)),
      .field_of_vec_of_strings_at_most_nine =
          WireNaturalConversionTraits<::fidl::VectorView<::fidl::StringView>,
                                      ::std::vector<::std::string>>::
              ToNatural(std::move(src.field_of_vec_of_strings_at_most_nine)),
      .field_of_vec_of_strings_at_most_5 =
          WireNaturalConversionTraits<::fidl::VectorView<::fidl::StringView>,
                                      ::std::vector<::std::string>>::
              ToNatural(std::move(src.field_of_vec_of_strings_at_most_5)),
      .field_of_vec_of_ref_me_at_most_5 = WireNaturalConversionTraits<
          ::fidl::VectorView<::test_someotherlibrary::wire::ReferenceMe>,
          ::std::vector<::test_someotherlibrary::ReferenceMe>>::
          ToNatural(std::move(src.field_of_vec_of_ref_me_at_most_5)),
      .field_of_channel =
          WireNaturalConversionTraits<::zx::channel, ::zx::channel>::ToNatural(
              std::move(src.field_of_channel)),
      .field_of_client_end =
          WireNaturalConversionTraits<::zx::channel, ::zx::channel>::ToNatural(
              std::move(src.field_of_client_end)),
      .field_of_nullable_client_end =
          WireNaturalConversionTraits<::zx::channel, ::zx::channel>::ToNatural(
              std::move(src.field_of_nullable_client_end)),
  });
}
::test_typealiases::wire::ExampleOfUseOfAliases
WireNaturalConversionTraits<::test_typealiases::wire::ExampleOfUseOfAliases,
                            ::test_typealiases::ExampleOfUseOfAliases>::
    ToWire(fidl::AnyArena& arena,
           ::test_typealiases::ExampleOfUseOfAliases src) {
  return ::test_typealiases::wire::ExampleOfUseOfAliases{
      .field_of_u32 = WireNaturalConversionTraits<uint32_t, uint32_t>::ToWire(
          arena, std::move(src.field_of_u32())),
      .field_of_vec_of_strings =
          WireNaturalConversionTraits<::fidl::VectorView<::fidl::StringView>,
                                      ::std::vector<::std::string>>::
              ToWire(arena, std::move(src.field_of_vec_of_strings())),
      .field_of_vec_of_strings_at_most_nine =
          WireNaturalConversionTraits<::fidl::VectorView<::fidl::StringView>,
                                      ::std::vector<::std::string>>::
              ToWire(arena,
                     std::move(src.field_of_vec_of_strings_at_most_nine())),
      .field_of_vec_of_strings_at_most_5 =
          WireNaturalConversionTraits<::fidl::VectorView<::fidl::StringView>,
                                      ::std::vector<::std::string>>::
              ToWire(arena, std::move(src.field_of_vec_of_strings_at_most_5())),
      .field_of_vec_of_ref_me_at_most_5 = WireNaturalConversionTraits<
          ::fidl::VectorView<::test_someotherlibrary::wire::ReferenceMe>,
          ::std::vector<::test_someotherlibrary::ReferenceMe>>::
          ToWire(arena, std::move(src.field_of_vec_of_ref_me_at_most_5())),
      .field_of_channel =
          WireNaturalConversionTraits<::zx::channel, ::zx::channel>::ToWire(
              arena, std::move(src.field_of_channel())),
      .field_of_client_end =
          WireNaturalConversionTraits<::zx::channel, ::zx::channel>::ToWire(
              arena, std::move(src.field_of_client_end())),
      .field_of_nullable_client_end =
          WireNaturalConversionTraits<::zx::channel, ::zx::channel>::ToWire(
              arena, std::move(src.field_of_nullable_client_end())),
  };
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

#endif  // __Fuchsia__
}  // namespace internal
}  // namespace fidl
