blob: f666fb07d72fd1da8adb54d25d915c649b99603b [file] [log] [blame]
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <lib/sys/component/cpp/testing/internal/convert.h>
#include <lib/sys/component/cpp/testing/realm_builder_types.h>
namespace component_testing {
namespace internal {
// Convenience macro to check if a std::optional |field| is present
// and if so, populate the |fidl_type| with it. This is only
// used in |ConvertToFidl|.
#define ZX_COMPONENT_ADD_IF_PRESENT(cpp_type, field, fidl_type) \
if ((cpp_type)->field.has_value()) { \
(fidl_type).set_##field((cpp_type)->field.value()); \
}
// Same as above but wraps |field| value in a std::string.
#define ZX_COMPONENT_ADD_STR_IF_PRESENT(cpp_type, field, fidl_type) \
if ((cpp_type)->field.has_value()) { \
(fidl_type).set_##field(std::string((cpp_type)->field.value())); \
}
namespace {
// Basic implementation of std::get_if (since C++17).
// This function is namespaced with `cpp17` prefix because
// the name `get_if` clashes with std:: namespace usage *when* this
// library is compiled in C++17+.
// TODO(yaneury): Implement this in stdcompat library.
template <class T, class... Ts>
constexpr std::add_pointer_t<T> cpp17_get_if(cpp17::variant<Ts...>* pv) noexcept {
return pv && cpp17::holds_alternative<T>(*pv) ? std::addressof(cpp17::get<T, Ts...>(*pv))
: nullptr;
}
} // namespace
fuchsia::component::test::ChildOptions ConvertToFidl(const ChildOptions& options) {
fuchsia::component::test::ChildOptions result;
result.set_startup(options.startup_mode);
if (!options.environment.empty()) {
result.set_environment(std::string(options.environment));
}
return result;
}
fuchsia::component::decl::Ref ConvertToFidl(Ref ref) {
if (auto child_ref = cpp17_get_if<ChildRef>(&ref)) {
fuchsia::component::decl::ChildRef result;
result.name = std::string(child_ref->name);
return fuchsia::component::decl::Ref::WithChild(std::move(result));
}
if (auto _ = cpp17_get_if<ParentRef>(&ref)) {
return fuchsia::component::decl::Ref::WithParent(fuchsia::component::decl::ParentRef());
}
ZX_PANIC("ConvertToFidl(Ref) reached unreachable block!");
}
fuchsia::component::test::Capability2 ConvertToFidl(Capability capability) {
if (auto protocol = cpp17_get_if<Protocol>(&capability)) {
fuchsia::component::test::Protocol fidl_capability;
fidl_capability.set_name(std::string(protocol->name));
ZX_COMPONENT_ADD_STR_IF_PRESENT(protocol, as, fidl_capability);
ZX_COMPONENT_ADD_STR_IF_PRESENT(protocol, path, fidl_capability);
ZX_COMPONENT_ADD_IF_PRESENT(protocol, type, fidl_capability);
return fuchsia::component::test::Capability2::WithProtocol(std::move(fidl_capability));
}
if (auto service = cpp17_get_if<Service>(&capability)) {
fuchsia::component::test::Service fidl_capability;
fidl_capability.set_name(std::string(service->name));
ZX_COMPONENT_ADD_STR_IF_PRESENT(service, as, fidl_capability);
ZX_COMPONENT_ADD_STR_IF_PRESENT(service, path, fidl_capability);
return fuchsia::component::test::Capability2::WithService(std::move(fidl_capability));
}
if (auto directory = cpp17_get_if<Directory>(&capability)) {
fuchsia::component::test::Directory fidl_capability;
fidl_capability.set_name(std::string(directory->name));
ZX_COMPONENT_ADD_STR_IF_PRESENT(directory, as, fidl_capability);
ZX_COMPONENT_ADD_IF_PRESENT(directory, type, fidl_capability);
ZX_COMPONENT_ADD_STR_IF_PRESENT(directory, subdir, fidl_capability);
ZX_COMPONENT_ADD_IF_PRESENT(directory, rights, fidl_capability);
ZX_COMPONENT_ADD_STR_IF_PRESENT(directory, path, fidl_capability);
return fuchsia::component::test::Capability2::WithDirectory(std::move(fidl_capability));
}
if (auto storage = cpp17_get_if<Storage>(&capability)) {
fuchsia::component::test::Storage fidl_capability;
fidl_capability.set_name(std::string(storage->name));
ZX_COMPONENT_ADD_STR_IF_PRESENT(storage, as, fidl_capability);
ZX_COMPONENT_ADD_STR_IF_PRESENT(storage, path, fidl_capability);
return fuchsia::component::test::Capability2::WithStorage(std::move(fidl_capability));
}
ZX_PANIC("ConvertToFidl(Capability) reached unreachable block!");
}
} // namespace internal
} // namespace component_testing