From 1e19439b9493ff6409653c1abbf95f5699166159 Mon Sep 17 00:00:00 2001 From: Marc Rousavy Date: Thu, 22 Feb 2024 14:48:05 +0100 Subject: [PATCH] feat: Allow User to extend enums --- package/cpp/jsi/EnumMapper.h | 59 +++++++++------------------------- package/cpp/jsi/JSIConverter.h | 9 ++++-- package/cpp/test/TestEnum.h | 29 ++++++++++++++++- 3 files changed, 50 insertions(+), 47 deletions(-) diff --git a/package/cpp/jsi/EnumMapper.h b/package/cpp/jsi/EnumMapper.h index 45ca9185..084a6ac9 100644 --- a/package/cpp/jsi/EnumMapper.h +++ b/package/cpp/jsi/EnumMapper.h @@ -4,57 +4,30 @@ #pragma once -#include "test/TestEnum.h" -#include +#include +#include namespace margelo { -using namespace facebook; +namespace EnumMapper { + // Add these two methods in namespace "EnumMapper" to allow parsing a custom enum: + // 1. `static void convertJSUnionToEnum(const std::string& inUnion, Enum* outEnum)` + // 2. `static void convertEnumToJSUnion(Enum inEnum, std::string* outUnion)` -static std::runtime_error invalidUnion(const std::string jsUnion) { - return std::runtime_error("Cannot convert JS Value to Enum: Invalid Union value passed! (\"" + jsUnion + "\")"); -} -template static std::runtime_error invalidEnum(Enum passedEnum) { - return std::runtime_error("Cannot convert Enum to JS Value: Invalid Enum passed! (Value #" + std::to_string(passedEnum) + - " does not exist in " + typeid(Enum).name() + ")"); -} - -template struct EnumMapper { - static Enum fromJSUnion(const std::string&) { - static_assert(always_false::value, "This type is not supported by the EnumMapper!"); - return Enum(); + static std::runtime_error invalidUnion(const std::string& passedUnion) { + return std::runtime_error("Cannot convert JS Value to Enum: Invalid Union value passed! (\"" + std::string(passedUnion) + "\")"); } - static std::string toJSUnion(Enum) { - static_assert(always_false::value, "This type is not supported by the EnumMapper!"); - return std::string(); + static std::runtime_error invalidEnum(int passedEnum) { + return std::runtime_error("Cannot convert Enum to JS Value: Invalid Enum passed! (Value #" + std::to_string(passedEnum) + ")"); } -private: - template struct always_false : std::false_type {}; -}; - -template <> struct EnumMapper { -public: - static constexpr TestEnum fromJSUnion(const std::string& jsUnion) { - if (jsUnion == "first") - return FIRST; - if (jsUnion == "second") - return SECOND; - if (jsUnion == "third") - return THIRD; - throw invalidUnion(jsUnion); + static void convertJSUnionToEnum(const std::string& inUnion, int*) { + throw invalidUnion(inUnion); } - static std::string toJSUnion(TestEnum value) { - switch (value) { - case FIRST: - return "first"; - case SECOND: - return "second"; - case THIRD: - return "third"; - } - throw invalidEnum(value); + + static void convertEnumToJSUnion(int inEnum, std::string*) { + throw invalidEnum(inEnum); } -}; +} // namespace EnumMapper } // namespace margelo diff --git a/package/cpp/jsi/JSIConverter.h b/package/cpp/jsi/JSIConverter.h index 2320c7ae..20094973 100644 --- a/package/cpp/jsi/JSIConverter.h +++ b/package/cpp/jsi/JSIConverter.h @@ -104,11 +104,14 @@ template struct JSIConverter> { template struct JSIConverter::value>> { static TEnum fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) { std::string string = arg.asString(runtime).utf8(runtime); - return EnumMapper::fromJSUnion(string); + TEnum outEnum; + EnumMapper::convertJSUnionToEnum(string, &outEnum); + return outEnum; } static jsi::Value toJSI(jsi::Runtime& runtime, TEnum arg) { - std::string string = EnumMapper::toJSUnion(arg); - return jsi::String::createFromUtf8(runtime, string); + std::string outUnion; + EnumMapper::convertEnumToJSUnion(arg, &outUnion); + return jsi::String::createFromUtf8(runtime, outUnion); } }; diff --git a/package/cpp/test/TestEnum.h b/package/cpp/test/TestEnum.h index 87775541..c1b983dd 100644 --- a/package/cpp/test/TestEnum.h +++ b/package/cpp/test/TestEnum.h @@ -10,4 +10,31 @@ namespace margelo { enum TestEnum { FIRST, SECOND, THIRD }; -} \ No newline at end of file +namespace EnumMapper { + static void convertJSUnionToEnum(const std::string& inUnion, TestEnum* outEnum) { + if (inUnion == "first") + *outEnum = FIRST; + else if (inUnion == "second") + *outEnum = SECOND; + else if (inUnion == "third") + *outEnum = THIRD; + else + throw invalidUnion(inUnion); + } + static void convertEnumToJSUnion(TestEnum inEnum, std::string* outUnion) { + switch (inEnum) { + case FIRST: + *outUnion = "first"; + break; + case SECOND: + *outUnion = "second"; + break; + case THIRD: + *outUnion = "third"; + break; + default: + throw invalidEnum(inEnum); + } + } +} // namespace EnumMapper +} // namespace margelo \ No newline at end of file