UNPKG

nitro-codegen

Version:

The code-generator for react-native-nitro-modules.

89 lines (79 loc) 3.11 kB
import { createFileMetadataString } from './../helpers.js'; import { indent, toLowerCamelCase } from '../../utils.js'; import { includeNitroHeader } from './includeNitroHeader.js'; import { NitroConfig } from '../../config/NitroConfig.js'; /** * Creates a C++ enum that converts to a TypeScript union (aka just strings). */ export function createCppUnion(typename, enumMembers) { const cppEnumMembers = enumMembers .map((m, i) => `${m.name} SWIFT_NAME(${toLowerCamelCase(m.name)}) = ${i},`) .join('\n'); const cppFromJsiHashCases = enumMembers .map((v) => `case hashString("${v.stringValue}"): return ${typename}::${v.name};`.trim()) .join('\n'); const cppToJsiCases = enumMembers .map((v) => `case ${typename}::${v.name}: return JSIConverter<std::string>::toJSI(runtime, "${v.stringValue}");`) .join('\n'); const cppCanConvertCases = enumMembers .map((m) => `case hashString("${m.stringValue}"):`) .join('\n'); const cxxNamespace = NitroConfig.getCxxNamespace('c++'); const cppCode = ` ${createFileMetadataString(`${typename}.hpp`)} #pragma once ${includeNitroHeader('NitroHash.hpp')} ${includeNitroHeader('JSIConverter.hpp')} ${includeNitroHeader('NitroDefines.hpp')} namespace ${cxxNamespace} { /** * An enum which can be represented as a JavaScript union (${typename}). */ enum class ${typename} { ${indent(cppEnumMembers, ' ')} } CLOSED_ENUM; } // namespace ${cxxNamespace} namespace margelo::nitro { using namespace ${cxxNamespace}; // C++ ${typename} <> JS ${typename} (union) template <> struct JSIConverter<${typename}> final { static inline ${typename} fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) { std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, arg); switch (hashString(unionValue.c_str(), unionValue.size())) { ${indent(cppFromJsiHashCases, ' ')} default: [[unlikely]] throw std::invalid_argument("Cannot convert \\"" + unionValue + "\\" to enum ${typename} - invalid value!"); } } static inline jsi::Value toJSI(jsi::Runtime& runtime, ${typename} arg) { switch (arg) { ${indent(cppToJsiCases, ' ')} default: [[unlikely]] throw std::invalid_argument("Cannot convert ${typename} to JS - invalid value: " + std::to_string(static_cast<int>(arg)) + "!"); } } static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) { if (!value.isString()) { return false; } std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, value); switch (hashString(unionValue.c_str(), unionValue.size())) { ${indent(cppCanConvertCases, ' ')} return true; default: return false; } } }; } // namespace margelo::nitro `; return { content: cppCode, name: `${typename}.hpp`, subdirectory: [], language: 'c++', platform: 'shared', }; }