diff --git a/docs/docs/types/variants.md b/docs/docs/types/variants.md index ec7c65a05..c7bedaebe 100644 --- a/docs/docs/types/variants.md +++ b/docs/docs/types/variants.md @@ -16,9 +16,38 @@ While variants are still very efficient, they need runtime-checks for type conve which comes with a tiny overhead compared to all other statically defined types. If possible, **avoid variants**. ::: -## No literal values +## Variants with String Enums -A variant can only consist of types, not of literal values. +Variants can contain [string enums (unions)](custom-enums#typescript-union) alongside other types like `boolean` or `number`: + +```ts +type Status = 'pending' | 'complete' | 'failed' + +interface Task extends HybridObject<{ … }> { + getStatus(): boolean | Status +} +``` + +This generates a proper variant type (`std::variant` in C++) where `Status` is preserved as an enum. + +You can also combine multiple string enums in a single variant: + +```ts +type Color = 'red' | 'green' | 'blue' +type Size = 'small' | 'medium' | 'large' + +interface Item extends HybridObject<{ … }> { + getAttribute(): Color | Size +} +``` + +:::warning +String enums in the same variant must have **distinct values**. Overlapping values (e.g., both enums containing `'default'`) will cause an error because Nitrogen cannot determine which enum a shared value belongs to at runtime. +::: + +## No inline literal values + +A variant can only consist of types, not of inline literal values. ```ts export interface Person extends HybridObject<{ … }> { diff --git a/packages/nitrogen/src/nitrogen.ts b/packages/nitrogen/src/nitrogen.ts index 3fe66d57a..0659c6fe8 100644 --- a/packages/nitrogen/src/nitrogen.ts +++ b/packages/nitrogen/src/nitrogen.ts @@ -20,6 +20,7 @@ import chalk from 'chalk' import { groupByPlatform, type SourceFile } from './syntax/SourceFile.js' import { Logger } from './Logger.js' import { NitroConfig } from './config/NitroConfig.js' +import { initializeTypeCreation } from './syntax/createType.js' import { createIOSAutolinking } from './autolinking/createIOSAutolinking.js' import { createAndroidAutolinking } from './autolinking/createAndroidAutolinking.js' import type { Autolinking } from './autolinking/Autolinking.js' @@ -61,6 +62,9 @@ export async function runNitrogen({ }) project.addSourceFilesAtPaths(globPattern) + // Initialize type creation context (needed for enum reconstruction from flattened unions) + initializeTypeCreation(project) + // Loop through all source files to log them Logger.info( chalk.reset( diff --git a/packages/nitrogen/src/syntax/createType.ts b/packages/nitrogen/src/syntax/createType.ts index 47af305ab..61945af37 100644 --- a/packages/nitrogen/src/syntax/createType.ts +++ b/packages/nitrogen/src/syntax/createType.ts @@ -1,4 +1,10 @@ -import { ts, Type as TSMorphType, type Signature } from 'ts-morph' +import { + ts, + Type as TSMorphType, + type Project, + type Signature, + type TypeAliasDeclaration, +} from 'ts-morph' import type { Type } from './types/Type.js' import { BooleanType } from './types/BooleanType.js' import { NumberType } from './types/NumberType.js' @@ -45,6 +51,27 @@ import { getCustomTypeConfig } from './getCustomTypeConfig.js' import { compareLooselyness } from './helpers.js' import { NullType } from './types/NullType.js' +// Cache of type alias name -> TypeAliasDeclarations for efficient lookups during enum reconstruction. +// Multiple declarations may exist for the same name across different files. +let typeAliasCache: Map | undefined + +/** + * Initialize the type creation context with the ts-morph Project. + * Must be called before createType() to enable enum reconstruction from flattened unions. + */ +export function initializeTypeCreation(project: Project): void { + // Build type alias cache for efficient lookups + typeAliasCache = new Map() + for (const sf of project.getSourceFiles()) { + for (const ta of sf.getTypeAliases()) { + const name = ta.getName() + const existing = typeAliasCache.get(name) ?? [] + existing.push(ta) + typeAliasCache.set(name, existing) + } + } +} + function getHybridObjectName(type: TSMorphType): string { const symbol = isHybridView(type) ? type.getAliasSymbol() : type.getSymbol() if (symbol == null) { @@ -75,6 +102,81 @@ function removeDuplicates(types: Type[]): Type[] { }) } +/** + * When TypeScript flattens a union like `boolean | FooBar` into `boolean | 'foo' | 'bar'`, + * we lose the information that 'foo' and 'bar' came from the named type `FooBar`. + * This function reconstructs enum types by parsing the type text for named types + * and matching their values against the string literals in the union. + */ +function reconstructEnumTypesFromStringLiterals( + _type: TSMorphType, + stringLiterals: TSMorphType[] +): { enumTypes: EnumType[]; uncoveredLiterals: TSMorphType[] } { + const stringLiteralValues = new Set(stringLiterals.map((t) => t.getText())) + const coveredLiterals = new Set() + const enumTypes: EnumType[] = [] + + if (typeAliasCache == null) { + throw new Error( + 'initializeTypeCreation() must be called before processing types with string literal unions' + ) + } + + // Collect all candidate enums whose values are all present in our string literals + const candidateEnums: { name: string; enumType: EnumType; values: Set }[] = [] + + for (const typeAliases of typeAliasCache.values()) { + for (const typeAlias of typeAliases) { + const aliasType = typeAlias.getType() + if (!aliasType.isUnion() || !aliasType.getAliasSymbol()) continue + + const aliasUnionTypes = aliasType.getUnionTypes() + const isStringLiteralEnum = aliasUnionTypes.every((t) => + t.isStringLiteral() + ) + if (!isStringLiteralEnum) continue + + const enumValues = aliasUnionTypes.map((t) => t.getText()) + const allValuesPresent = enumValues.every((v) => + stringLiteralValues.has(v) + ) + if (!allValuesPresent) continue + + candidateEnums.push({ + name: typeAlias.getName(), + enumType: new EnumType(typeAlias.getName(), aliasType), + values: new Set(enumValues), + }) + } + } + + // Check for overlapping enums - if any two candidate enums share a value, it's ambiguous + for (let i = 0; i < candidateEnums.length; i++) { + for (let j = i + 1; j < candidateEnums.length; j++) { + const enumA = candidateEnums[i]! + const enumB = candidateEnums[j]! + for (const value of enumA.values) { + if (enumB.values.has(value)) { + throw new Error( + `Cannot create variant with overlapping string enum types: ${enumA.name} and ${enumB.name} both contain ${value}. Use enums with distinct values.` + ) + } + } + } + } + + // No overlaps - add all candidate enums + for (const candidate of candidateEnums) { + enumTypes.push(candidate.enumType) + candidate.values.forEach((v) => coveredLiterals.add(v)) + } + + const uncoveredLiterals = stringLiterals.filter( + (t) => !coveredLiterals.has(t.getText()) + ) + return { enumTypes, uncoveredLiterals } +} + type Tuple< T, N extends number, @@ -287,25 +389,68 @@ export function createType( ) const isEnumUnion = nonNullTypes.every((t) => t.isStringLiteral()) if (isEnumUnion) { - // It consists only of string literaly - that means it's describing an enum! + // It consists only of string literals - that means it's describing an enum! const symbol = type.getNonNullableType().getAliasSymbol() if (symbol == null) { - // If there is no alias, it is an inline union instead of a separate type declaration! - throw new Error( - `Inline union types ("${type.getText()}") are not supported by Nitrogen!\n` + - `Extract the union to a separate type, and re-run nitrogen!` - ) + // No alias symbol - could be multiple enum types flattened together (e.g., SomeEnum | SomeOtherEnum) + // Try to reconstruct the original enum types from the string literals + const { enumTypes, uncoveredLiterals } = + reconstructEnumTypesFromStringLiterals(type, nonNullTypes) + + if (enumTypes.length === 0 || uncoveredLiterals.length > 0) { + // Could not reconstruct enums - it's an inline union + throw new Error( + `Inline union types ("${type.getText()}") are not supported by Nitrogen!\n` + + `Extract the union to a separate type, and re-run nitrogen!` + ) + } + + if (enumTypes.length === 1) { + // Single enum reconstructed + return enumTypes[0]! + } + + // Multiple enums - return as variant + const name = type.getAliasSymbol()?.getName() + return new VariantType(enumTypes, name) } const typename = symbol.getEscapedName() return new EnumType(typename, type) } else { // It consists of different types - that means it's a variant! - let variants = type + const unionTypes = type .getUnionTypes() // Filter out any undefineds/voids, as those are already treated as `isOptional`. .filter((t) => !t.isUndefined() && !t.isVoid()) - .map((t) => createType(language, t, false)) - .toSorted(compareLooselyness) + + // Separate string literals from other types + // String literals might belong to a named enum type that got flattened + const stringLiterals = unionTypes.filter((t) => t.isStringLiteral()) + const otherTypes = unionTypes.filter((t) => !t.isStringLiteral()) + + let variants: Type[] = [] + + // Process non-string-literal types + for (const t of otherTypes) { + variants.push(createType(language, t, false)) + } + + // For string literals, try to find named enum types from the original type text. + // TypeScript flattens `boolean | FooBar` into `boolean | 'foo' | 'bar'`, losing the + // enum type info. We reconstruct it by parsing the type text for named types. + if (stringLiterals.length > 0) { + const { enumTypes, uncoveredLiterals } = + reconstructEnumTypesFromStringLiterals(type, stringLiterals) + variants.push(...enumTypes) + + if (uncoveredLiterals.length > 0) { + throw new Error( + `String literal ${uncoveredLiterals[0]!.getText()} cannot be represented in C++ because it is ambiguous between a string and a discriminating union enum.` + ) + } + } + + variants = variants.toSorted(compareLooselyness) variants = removeDuplicates(variants) if (variants.length === 1) { diff --git a/packages/react-native-nitro-test/android/src/main/java/com/margelo/nitro/test/HybridTestObjectKotlin.kt b/packages/react-native-nitro-test/android/src/main/java/com/margelo/nitro/test/HybridTestObjectKotlin.kt index 7f959178a..abdbaac59 100644 --- a/packages/react-native-nitro-test/android/src/main/java/com/margelo/nitro/test/HybridTestObjectKotlin.kt +++ b/packages/react-native-nitro-test/android/src/main/java/com/margelo/nitro/test/HybridTestObjectKotlin.kt @@ -472,6 +472,26 @@ class HybridTestObjectKotlin : HybridTestObjectSwiftKotlinSpec() { return variant } + override fun getVariantSomeEnum(variant: Variant_Boolean_SomeEnum): Variant_Boolean_SomeEnum { + return variant + } + + override fun getVariantMultipleEnums(variant: Variant_SomeEnum_SomeOtherEnum): Variant_SomeEnum_SomeOtherEnum { + return variant + } + + override fun getVariantStringAndEnum(variant: String): String { + return variant + } + + override fun getVariantThreeTypes(variant: Variant_Boolean_SomeEnum_SomeOtherEnum): Variant_Boolean_SomeEnum_SomeOtherEnum { + return variant + } + + override fun getVariantNumberAndEnum(variant: Variant_SomeEnum_Double): Variant_SomeEnum_Double { + return variant + } + override fun getVariantObjects(variant: Variant_Car_Person): Variant_Car_Person { return variant } diff --git a/packages/react-native-nitro-test/cpp/HybridTestObjectCpp.cpp b/packages/react-native-nitro-test/cpp/HybridTestObjectCpp.cpp index bd838e087..6de2bca0f 100644 --- a/packages/react-native-nitro-test/cpp/HybridTestObjectCpp.cpp +++ b/packages/react-native-nitro-test/cpp/HybridTestObjectCpp.cpp @@ -347,6 +347,26 @@ std::variant HybridTestObjectCpp::getVariantWeirdNumbers return variant; } +std::variant HybridTestObjectCpp::getVariantSomeEnum(const std::variant& variant) { + return variant; +} + +std::variant HybridTestObjectCpp::getVariantMultipleEnums(const std::variant& variant) { + return variant; +} + +std::string HybridTestObjectCpp::getVariantStringAndEnum(const std::string& variant) { + return variant; +} + +std::variant HybridTestObjectCpp::getVariantThreeTypes(const std::variant& variant) { + return variant; +} + +std::variant HybridTestObjectCpp::getVariantNumberAndEnum(const std::variant& variant) { + return variant; +} + std::variant HybridTestObjectCpp::getVariantObjects(const std::variant& variant) { return variant; } diff --git a/packages/react-native-nitro-test/cpp/HybridTestObjectCpp.hpp b/packages/react-native-nitro-test/cpp/HybridTestObjectCpp.hpp index 069fb104f..294ec6fd1 100644 --- a/packages/react-native-nitro-test/cpp/HybridTestObjectCpp.hpp +++ b/packages/react-native-nitro-test/cpp/HybridTestObjectCpp.hpp @@ -129,6 +129,11 @@ class HybridTestObjectCpp : public HybridTestObjectCppSpec { std::variant getVariantEnum(const std::variant& variant) override; std::variant getVariantWeirdNumbersEnum(const std::variant& variant) override; + std::variant getVariantSomeEnum(const std::variant& variant) override; + std::variant getVariantMultipleEnums(const std::variant& variant) override; + std::string getVariantStringAndEnum(const std::string& variant) override; + std::variant getVariantThreeTypes(const std::variant& variant) override; + std::variant getVariantNumberAndEnum(const std::variant& variant) override; std::variant getVariantObjects(const std::variant& variant) override; std::variant, Person> getVariantHybrid(const std::variant, Person>& variant) override; diff --git a/packages/react-native-nitro-test/ios/HybridTestObjectSwift.swift b/packages/react-native-nitro-test/ios/HybridTestObjectSwift.swift index 0bd3ef789..8a0a6773b 100644 --- a/packages/react-native-nitro-test/ios/HybridTestObjectSwift.swift +++ b/packages/react-native-nitro-test/ios/HybridTestObjectSwift.swift @@ -343,6 +343,30 @@ class HybridTestObjectSwift: HybridTestObjectSwiftKotlinSpec { return variant } + func getVariantSomeEnum(variant: Variant_Bool_SomeEnum) throws -> Variant_Bool_SomeEnum { + return variant + } + + func getVariantMultipleEnums(variant: Variant_SomeEnum_SomeOtherEnum) throws + -> Variant_SomeEnum_SomeOtherEnum + { + return variant + } + + func getVariantStringAndEnum(variant: String) throws -> String { + return variant + } + + func getVariantThreeTypes(variant: Variant_Bool_SomeEnum_SomeOtherEnum) throws + -> Variant_Bool_SomeEnum_SomeOtherEnum + { + return variant + } + + func getVariantNumberAndEnum(variant: Variant_SomeEnum_Double) throws -> Variant_SomeEnum_Double { + return variant + } + func getVariantObjects(variant: Variant_Car_Person) throws -> Variant_Car_Person { return variant } diff --git a/packages/react-native-nitro-test/nitrogen/generated/android/NitroTest+autolinking.cmake b/packages/react-native-nitro-test/nitrogen/generated/android/NitroTest+autolinking.cmake index cb76283f0..fd563fb9a 100644 --- a/packages/react-native-nitro-test/nitrogen/generated/android/NitroTest+autolinking.cmake +++ b/packages/react-native-nitro-test/nitrogen/generated/android/NitroTest+autolinking.cmake @@ -53,6 +53,10 @@ target_sources( ../nitrogen/generated/android/c++/JVariant_______Unit_Double.cpp ../nitrogen/generated/android/c++/JVariant_Boolean_OldEnum.cpp ../nitrogen/generated/android/c++/JVariant_Boolean_WeirdNumbersEnum.cpp + ../nitrogen/generated/android/c++/JVariant_Boolean_SomeEnum.cpp + ../nitrogen/generated/android/c++/JVariant_SomeEnum_SomeOtherEnum.cpp + ../nitrogen/generated/android/c++/JVariant_Boolean_SomeEnum_SomeOtherEnum.cpp + ../nitrogen/generated/android/c++/JVariant_SomeEnum_Double.cpp ../nitrogen/generated/android/c++/JVariant_Car_Person.cpp ../nitrogen/generated/android/c++/JVariant_HybridBaseSpec_OptionalWrapper.cpp ../nitrogen/generated/android/c++/JCoreTypesVariant.cpp diff --git a/packages/react-native-nitro-test/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.cpp b/packages/react-native-nitro-test/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.cpp index d11952344..32215db39 100644 --- a/packages/react-native-nitro-test/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.cpp +++ b/packages/react-native-nitro-test/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.cpp @@ -31,6 +31,10 @@ namespace margelo::nitro::test { struct OptionalWrapper; } namespace margelo::nitro::test { struct OptionalCallback; } // Forward declaration of `WeirdNumbersEnum` to properly resolve imports. namespace margelo::nitro::test { enum class WeirdNumbersEnum; } +// Forward declaration of `SomeEnum` to properly resolve imports. +namespace margelo::nitro::test { enum class SomeEnum; } +// Forward declaration of `SomeOtherEnum` to properly resolve imports. +namespace margelo::nitro::test { enum class SomeOtherEnum; } // Forward declaration of `HybridBaseSpec` to properly resolve imports. namespace margelo::nitro::test { class HybridBaseSpec; } // Forward declaration of `HybridSomeExternalObjectSpec` to properly resolve imports. @@ -96,6 +100,14 @@ namespace margelo::nitro::test { class HybridTestViewSpec; } #include "WeirdNumbersEnum.hpp" #include "JVariant_Boolean_WeirdNumbersEnum.hpp" #include "JWeirdNumbersEnum.hpp" +#include "SomeEnum.hpp" +#include "JVariant_Boolean_SomeEnum.hpp" +#include "JSomeEnum.hpp" +#include "SomeOtherEnum.hpp" +#include "JVariant_SomeEnum_SomeOtherEnum.hpp" +#include "JSomeOtherEnum.hpp" +#include "JVariant_Boolean_SomeEnum_SomeOtherEnum.hpp" +#include "JVariant_SomeEnum_Double.hpp" #include "JVariant_Car_Person.hpp" #include "JNamedVariant.hpp" #include "HybridBaseSpec.hpp" @@ -1144,6 +1156,31 @@ namespace margelo::nitro::test { auto __result = method(_javaPart, JVariant_Boolean_WeirdNumbersEnum::fromCpp(variant)); return __result->toCpp(); } + std::variant JHybridTestObjectSwiftKotlinSpec::getVariantSomeEnum(const std::variant& variant) { + static const auto method = javaClassStatic()->getMethod(jni::alias_ref /* variant */)>("getVariantSomeEnum"); + auto __result = method(_javaPart, JVariant_Boolean_SomeEnum::fromCpp(variant)); + return __result->toCpp(); + } + std::variant JHybridTestObjectSwiftKotlinSpec::getVariantMultipleEnums(const std::variant& variant) { + static const auto method = javaClassStatic()->getMethod(jni::alias_ref /* variant */)>("getVariantMultipleEnums"); + auto __result = method(_javaPart, JVariant_SomeEnum_SomeOtherEnum::fromCpp(variant)); + return __result->toCpp(); + } + std::string JHybridTestObjectSwiftKotlinSpec::getVariantStringAndEnum(const std::string& variant) { + static const auto method = javaClassStatic()->getMethod(jni::alias_ref /* variant */)>("getVariantStringAndEnum"); + auto __result = method(_javaPart, jni::make_jstring(variant)); + return __result->toStdString(); + } + std::variant JHybridTestObjectSwiftKotlinSpec::getVariantThreeTypes(const std::variant& variant) { + static const auto method = javaClassStatic()->getMethod(jni::alias_ref /* variant */)>("getVariantThreeTypes"); + auto __result = method(_javaPart, JVariant_Boolean_SomeEnum_SomeOtherEnum::fromCpp(variant)); + return __result->toCpp(); + } + std::variant JHybridTestObjectSwiftKotlinSpec::getVariantNumberAndEnum(const std::variant& variant) { + static const auto method = javaClassStatic()->getMethod(jni::alias_ref /* variant */)>("getVariantNumberAndEnum"); + auto __result = method(_javaPart, JVariant_SomeEnum_Double::fromCpp(variant)); + return __result->toCpp(); + } std::variant JHybridTestObjectSwiftKotlinSpec::getVariantObjects(const std::variant& variant) { static const auto method = javaClassStatic()->getMethod(jni::alias_ref /* variant */)>("getVariantObjects"); auto __result = method(_javaPart, JVariant_Car_Person::fromCpp(variant)); diff --git a/packages/react-native-nitro-test/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.hpp b/packages/react-native-nitro-test/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.hpp index 4bd84767d..2a5cbbba9 100644 --- a/packages/react-native-nitro-test/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.hpp +++ b/packages/react-native-nitro-test/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.hpp @@ -158,6 +158,11 @@ namespace margelo::nitro::test { std::variant passVariant(const std::variant, std::vector, std::string, double>& either) override; std::variant getVariantEnum(const std::variant& variant) override; std::variant getVariantWeirdNumbersEnum(const std::variant& variant) override; + std::variant getVariantSomeEnum(const std::variant& variant) override; + std::variant getVariantMultipleEnums(const std::variant& variant) override; + std::string getVariantStringAndEnum(const std::string& variant) override; + std::variant getVariantThreeTypes(const std::variant& variant) override; + std::variant getVariantNumberAndEnum(const std::variant& variant) override; std::variant getVariantObjects(const std::variant& variant) override; std::variant passNamedVariant(const std::variant& variant) override; std::variant, OptionalWrapper> passAllEmptyObjectVariant(const std::variant, OptionalWrapper>& variant) override; diff --git a/packages/react-native-nitro-test/nitrogen/generated/android/c++/JSomeEnum.hpp b/packages/react-native-nitro-test/nitrogen/generated/android/c++/JSomeEnum.hpp new file mode 100644 index 000000000..4ad7d2215 --- /dev/null +++ b/packages/react-native-nitro-test/nitrogen/generated/android/c++/JSomeEnum.hpp @@ -0,0 +1,59 @@ +/// +/// JSomeEnum.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © 2025 Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include "SomeEnum.hpp" + +namespace margelo::nitro::test { + + using namespace facebook; + + /** + * The C++ JNI bridge between the C++ enum "SomeEnum" and the the Kotlin enum "SomeEnum". + */ + struct JSomeEnum final: public jni::JavaClass { + public: + static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/test/SomeEnum;"; + + public: + /** + * Convert this Java/Kotlin-based enum to the C++ enum SomeEnum. + */ + [[maybe_unused]] + [[nodiscard]] + SomeEnum toCpp() const { + static const auto clazz = javaClassStatic(); + static const auto fieldOrdinal = clazz->getField("value"); + int ordinal = this->getFieldValue(fieldOrdinal); + return static_cast(ordinal); + } + + public: + /** + * Create a Java/Kotlin-based enum with the given C++ enum's value. + */ + [[maybe_unused]] + static jni::alias_ref fromCpp(SomeEnum value) { + static const auto clazz = javaClassStatic(); + static const auto fieldFOO = clazz->getStaticField("FOO"); + static const auto fieldBAR = clazz->getStaticField("BAR"); + + switch (value) { + case SomeEnum::FOO: + return clazz->getStaticFieldValue(fieldFOO); + case SomeEnum::BAR: + return clazz->getStaticFieldValue(fieldBAR); + default: + std::string stringValue = std::to_string(static_cast(value)); + throw std::invalid_argument("Invalid enum value (" + stringValue + "!"); + } + } + }; + +} // namespace margelo::nitro::test diff --git a/packages/react-native-nitro-test/nitrogen/generated/android/c++/JSomeOtherEnum.hpp b/packages/react-native-nitro-test/nitrogen/generated/android/c++/JSomeOtherEnum.hpp new file mode 100644 index 000000000..49cd3d81d --- /dev/null +++ b/packages/react-native-nitro-test/nitrogen/generated/android/c++/JSomeOtherEnum.hpp @@ -0,0 +1,59 @@ +/// +/// JSomeOtherEnum.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © 2025 Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include "SomeOtherEnum.hpp" + +namespace margelo::nitro::test { + + using namespace facebook; + + /** + * The C++ JNI bridge between the C++ enum "SomeOtherEnum" and the the Kotlin enum "SomeOtherEnum". + */ + struct JSomeOtherEnum final: public jni::JavaClass { + public: + static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/test/SomeOtherEnum;"; + + public: + /** + * Convert this Java/Kotlin-based enum to the C++ enum SomeOtherEnum. + */ + [[maybe_unused]] + [[nodiscard]] + SomeOtherEnum toCpp() const { + static const auto clazz = javaClassStatic(); + static const auto fieldOrdinal = clazz->getField("value"); + int ordinal = this->getFieldValue(fieldOrdinal); + return static_cast(ordinal); + } + + public: + /** + * Create a Java/Kotlin-based enum with the given C++ enum's value. + */ + [[maybe_unused]] + static jni::alias_ref fromCpp(SomeOtherEnum value) { + static const auto clazz = javaClassStatic(); + static const auto fieldBAZ = clazz->getStaticField("BAZ"); + static const auto fieldQUX = clazz->getStaticField("QUX"); + + switch (value) { + case SomeOtherEnum::BAZ: + return clazz->getStaticFieldValue(fieldBAZ); + case SomeOtherEnum::QUX: + return clazz->getStaticFieldValue(fieldQUX); + default: + std::string stringValue = std::to_string(static_cast(value)); + throw std::invalid_argument("Invalid enum value (" + stringValue + "!"); + } + } + }; + +} // namespace margelo::nitro::test diff --git a/packages/react-native-nitro-test/nitrogen/generated/android/c++/JVariant_Boolean_SomeEnum.cpp b/packages/react-native-nitro-test/nitrogen/generated/android/c++/JVariant_Boolean_SomeEnum.cpp new file mode 100644 index 000000000..fa31d0f30 --- /dev/null +++ b/packages/react-native-nitro-test/nitrogen/generated/android/c++/JVariant_Boolean_SomeEnum.cpp @@ -0,0 +1,26 @@ +/// +/// JVariant_Boolean_SomeEnum.cpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © 2025 Marc Rousavy @ Margelo +/// + +#include "JVariant_Boolean_SomeEnum.hpp" + +namespace margelo::nitro::test { + /** + * Converts JVariant_Boolean_SomeEnum to std::variant + */ + std::variant JVariant_Boolean_SomeEnum::toCpp() const { + if (isInstanceOf(JVariant_Boolean_SomeEnum_impl::First::javaClassStatic())) { + // It's a `bool` + auto jniValue = static_cast(this)->getValue(); + return static_cast(jniValue); + } else if (isInstanceOf(JVariant_Boolean_SomeEnum_impl::Second::javaClassStatic())) { + // It's a `SomeEnum` + auto jniValue = static_cast(this)->getValue(); + return jniValue->toCpp(); + } + throw std::invalid_argument("Variant is unknown Kotlin instance!"); + } +} // namespace margelo::nitro::test diff --git a/packages/react-native-nitro-test/nitrogen/generated/android/c++/JVariant_Boolean_SomeEnum.hpp b/packages/react-native-nitro-test/nitrogen/generated/android/c++/JVariant_Boolean_SomeEnum.hpp new file mode 100644 index 000000000..7bafe9b90 --- /dev/null +++ b/packages/react-native-nitro-test/nitrogen/generated/android/c++/JVariant_Boolean_SomeEnum.hpp @@ -0,0 +1,69 @@ +/// +/// JVariant_Boolean_SomeEnum.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © 2025 Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include + +#include "SomeEnum.hpp" +#include +#include "JSomeEnum.hpp" + +namespace margelo::nitro::test { + + using namespace facebook; + + /** + * The C++ JNI bridge between the C++ std::variant and the Java class "Variant_Boolean_SomeEnum". + */ + class JVariant_Boolean_SomeEnum: public jni::JavaClass { + public: + static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/test/Variant_Boolean_SomeEnum;"; + + static jni::local_ref create_0(jboolean value) { + static const auto method = javaClassStatic()->getStaticMethod("create"); + return method(javaClassStatic(), value); + } + static jni::local_ref create_1(jni::alias_ref value) { + static const auto method = javaClassStatic()->getStaticMethod)>("create"); + return method(javaClassStatic(), value); + } + + static jni::local_ref fromCpp(const std::variant& variant) { + switch (variant.index()) { + case 0: return create_0(std::get<0>(variant)); + case 1: return create_1(JSomeEnum::fromCpp(std::get<1>(variant))); + default: throw std::invalid_argument("Variant holds unknown index! (" + std::to_string(variant.index()) + ")"); + } + } + + [[nodiscard]] std::variant toCpp() const; + }; + + namespace JVariant_Boolean_SomeEnum_impl { + class First: public jni::JavaClass { + public: + static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/test/Variant_Boolean_SomeEnum$First;"; + + [[nodiscard]] jboolean getValue() const { + static const auto field = javaClassStatic()->getField("value"); + return getFieldValue(field); + } + }; + + class Second: public jni::JavaClass { + public: + static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/test/Variant_Boolean_SomeEnum$Second;"; + + [[nodiscard]] jni::local_ref getValue() const { + static const auto field = javaClassStatic()->getField("value"); + return getFieldValue(field); + } + }; + } // namespace JVariant_Boolean_SomeEnum_impl +} // namespace margelo::nitro::test diff --git a/packages/react-native-nitro-test/nitrogen/generated/android/c++/JVariant_Boolean_SomeEnum_SomeOtherEnum.cpp b/packages/react-native-nitro-test/nitrogen/generated/android/c++/JVariant_Boolean_SomeEnum_SomeOtherEnum.cpp new file mode 100644 index 000000000..5f36ed5f3 --- /dev/null +++ b/packages/react-native-nitro-test/nitrogen/generated/android/c++/JVariant_Boolean_SomeEnum_SomeOtherEnum.cpp @@ -0,0 +1,30 @@ +/// +/// JVariant_Boolean_SomeEnum_SomeOtherEnum.cpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © 2025 Marc Rousavy @ Margelo +/// + +#include "JVariant_Boolean_SomeEnum_SomeOtherEnum.hpp" + +namespace margelo::nitro::test { + /** + * Converts JVariant_Boolean_SomeEnum_SomeOtherEnum to std::variant + */ + std::variant JVariant_Boolean_SomeEnum_SomeOtherEnum::toCpp() const { + if (isInstanceOf(JVariant_Boolean_SomeEnum_SomeOtherEnum_impl::First::javaClassStatic())) { + // It's a `bool` + auto jniValue = static_cast(this)->getValue(); + return static_cast(jniValue); + } else if (isInstanceOf(JVariant_Boolean_SomeEnum_SomeOtherEnum_impl::Second::javaClassStatic())) { + // It's a `SomeEnum` + auto jniValue = static_cast(this)->getValue(); + return jniValue->toCpp(); + } else if (isInstanceOf(JVariant_Boolean_SomeEnum_SomeOtherEnum_impl::Third::javaClassStatic())) { + // It's a `SomeOtherEnum` + auto jniValue = static_cast(this)->getValue(); + return jniValue->toCpp(); + } + throw std::invalid_argument("Variant is unknown Kotlin instance!"); + } +} // namespace margelo::nitro::test diff --git a/packages/react-native-nitro-test/nitrogen/generated/android/c++/JVariant_Boolean_SomeEnum_SomeOtherEnum.hpp b/packages/react-native-nitro-test/nitrogen/generated/android/c++/JVariant_Boolean_SomeEnum_SomeOtherEnum.hpp new file mode 100644 index 000000000..7ff14a0a3 --- /dev/null +++ b/packages/react-native-nitro-test/nitrogen/generated/android/c++/JVariant_Boolean_SomeEnum_SomeOtherEnum.hpp @@ -0,0 +1,86 @@ +/// +/// JVariant_Boolean_SomeEnum_SomeOtherEnum.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © 2025 Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include + +#include "SomeEnum.hpp" +#include "SomeOtherEnum.hpp" +#include +#include "JSomeEnum.hpp" +#include "JSomeOtherEnum.hpp" + +namespace margelo::nitro::test { + + using namespace facebook; + + /** + * The C++ JNI bridge between the C++ std::variant and the Java class "Variant_Boolean_SomeEnum_SomeOtherEnum". + */ + class JVariant_Boolean_SomeEnum_SomeOtherEnum: public jni::JavaClass { + public: + static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/test/Variant_Boolean_SomeEnum_SomeOtherEnum;"; + + static jni::local_ref create_0(jboolean value) { + static const auto method = javaClassStatic()->getStaticMethod("create"); + return method(javaClassStatic(), value); + } + static jni::local_ref create_1(jni::alias_ref value) { + static const auto method = javaClassStatic()->getStaticMethod)>("create"); + return method(javaClassStatic(), value); + } + static jni::local_ref create_2(jni::alias_ref value) { + static const auto method = javaClassStatic()->getStaticMethod)>("create"); + return method(javaClassStatic(), value); + } + + static jni::local_ref fromCpp(const std::variant& variant) { + switch (variant.index()) { + case 0: return create_0(std::get<0>(variant)); + case 1: return create_1(JSomeEnum::fromCpp(std::get<1>(variant))); + case 2: return create_2(JSomeOtherEnum::fromCpp(std::get<2>(variant))); + default: throw std::invalid_argument("Variant holds unknown index! (" + std::to_string(variant.index()) + ")"); + } + } + + [[nodiscard]] std::variant toCpp() const; + }; + + namespace JVariant_Boolean_SomeEnum_SomeOtherEnum_impl { + class First: public jni::JavaClass { + public: + static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/test/Variant_Boolean_SomeEnum_SomeOtherEnum$First;"; + + [[nodiscard]] jboolean getValue() const { + static const auto field = javaClassStatic()->getField("value"); + return getFieldValue(field); + } + }; + + class Second: public jni::JavaClass { + public: + static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/test/Variant_Boolean_SomeEnum_SomeOtherEnum$Second;"; + + [[nodiscard]] jni::local_ref getValue() const { + static const auto field = javaClassStatic()->getField("value"); + return getFieldValue(field); + } + }; + + class Third: public jni::JavaClass { + public: + static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/test/Variant_Boolean_SomeEnum_SomeOtherEnum$Third;"; + + [[nodiscard]] jni::local_ref getValue() const { + static const auto field = javaClassStatic()->getField("value"); + return getFieldValue(field); + } + }; + } // namespace JVariant_Boolean_SomeEnum_SomeOtherEnum_impl +} // namespace margelo::nitro::test diff --git a/packages/react-native-nitro-test/nitrogen/generated/android/c++/JVariant_SomeEnum_Double.cpp b/packages/react-native-nitro-test/nitrogen/generated/android/c++/JVariant_SomeEnum_Double.cpp new file mode 100644 index 000000000..c4c91b5bb --- /dev/null +++ b/packages/react-native-nitro-test/nitrogen/generated/android/c++/JVariant_SomeEnum_Double.cpp @@ -0,0 +1,26 @@ +/// +/// JVariant_SomeEnum_Double.cpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © 2025 Marc Rousavy @ Margelo +/// + +#include "JVariant_SomeEnum_Double.hpp" + +namespace margelo::nitro::test { + /** + * Converts JVariant_SomeEnum_Double to std::variant + */ + std::variant JVariant_SomeEnum_Double::toCpp() const { + if (isInstanceOf(JVariant_SomeEnum_Double_impl::First::javaClassStatic())) { + // It's a `SomeEnum` + auto jniValue = static_cast(this)->getValue(); + return jniValue->toCpp(); + } else if (isInstanceOf(JVariant_SomeEnum_Double_impl::Second::javaClassStatic())) { + // It's a `double` + auto jniValue = static_cast(this)->getValue(); + return jniValue; + } + throw std::invalid_argument("Variant is unknown Kotlin instance!"); + } +} // namespace margelo::nitro::test diff --git a/packages/react-native-nitro-test/nitrogen/generated/android/c++/JVariant_SomeEnum_Double.hpp b/packages/react-native-nitro-test/nitrogen/generated/android/c++/JVariant_SomeEnum_Double.hpp new file mode 100644 index 000000000..a45a4fc90 --- /dev/null +++ b/packages/react-native-nitro-test/nitrogen/generated/android/c++/JVariant_SomeEnum_Double.hpp @@ -0,0 +1,69 @@ +/// +/// JVariant_SomeEnum_Double.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © 2025 Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include + +#include "SomeEnum.hpp" +#include +#include "JSomeEnum.hpp" + +namespace margelo::nitro::test { + + using namespace facebook; + + /** + * The C++ JNI bridge between the C++ std::variant and the Java class "Variant_SomeEnum_Double". + */ + class JVariant_SomeEnum_Double: public jni::JavaClass { + public: + static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/test/Variant_SomeEnum_Double;"; + + static jni::local_ref create_0(jni::alias_ref value) { + static const auto method = javaClassStatic()->getStaticMethod)>("create"); + return method(javaClassStatic(), value); + } + static jni::local_ref create_1(double value) { + static const auto method = javaClassStatic()->getStaticMethod("create"); + return method(javaClassStatic(), value); + } + + static jni::local_ref fromCpp(const std::variant& variant) { + switch (variant.index()) { + case 0: return create_0(JSomeEnum::fromCpp(std::get<0>(variant))); + case 1: return create_1(std::get<1>(variant)); + default: throw std::invalid_argument("Variant holds unknown index! (" + std::to_string(variant.index()) + ")"); + } + } + + [[nodiscard]] std::variant toCpp() const; + }; + + namespace JVariant_SomeEnum_Double_impl { + class First: public jni::JavaClass { + public: + static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/test/Variant_SomeEnum_Double$First;"; + + [[nodiscard]] jni::local_ref getValue() const { + static const auto field = javaClassStatic()->getField("value"); + return getFieldValue(field); + } + }; + + class Second: public jni::JavaClass { + public: + static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/test/Variant_SomeEnum_Double$Second;"; + + [[nodiscard]] double getValue() const { + static const auto field = javaClassStatic()->getField("value"); + return getFieldValue(field); + } + }; + } // namespace JVariant_SomeEnum_Double_impl +} // namespace margelo::nitro::test diff --git a/packages/react-native-nitro-test/nitrogen/generated/android/c++/JVariant_SomeEnum_SomeOtherEnum.cpp b/packages/react-native-nitro-test/nitrogen/generated/android/c++/JVariant_SomeEnum_SomeOtherEnum.cpp new file mode 100644 index 000000000..8dd28fb73 --- /dev/null +++ b/packages/react-native-nitro-test/nitrogen/generated/android/c++/JVariant_SomeEnum_SomeOtherEnum.cpp @@ -0,0 +1,26 @@ +/// +/// JVariant_SomeEnum_SomeOtherEnum.cpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © 2025 Marc Rousavy @ Margelo +/// + +#include "JVariant_SomeEnum_SomeOtherEnum.hpp" + +namespace margelo::nitro::test { + /** + * Converts JVariant_SomeEnum_SomeOtherEnum to std::variant + */ + std::variant JVariant_SomeEnum_SomeOtherEnum::toCpp() const { + if (isInstanceOf(JVariant_SomeEnum_SomeOtherEnum_impl::First::javaClassStatic())) { + // It's a `SomeEnum` + auto jniValue = static_cast(this)->getValue(); + return jniValue->toCpp(); + } else if (isInstanceOf(JVariant_SomeEnum_SomeOtherEnum_impl::Second::javaClassStatic())) { + // It's a `SomeOtherEnum` + auto jniValue = static_cast(this)->getValue(); + return jniValue->toCpp(); + } + throw std::invalid_argument("Variant is unknown Kotlin instance!"); + } +} // namespace margelo::nitro::test diff --git a/packages/react-native-nitro-test/nitrogen/generated/android/c++/JVariant_SomeEnum_SomeOtherEnum.hpp b/packages/react-native-nitro-test/nitrogen/generated/android/c++/JVariant_SomeEnum_SomeOtherEnum.hpp new file mode 100644 index 000000000..c4058b78a --- /dev/null +++ b/packages/react-native-nitro-test/nitrogen/generated/android/c++/JVariant_SomeEnum_SomeOtherEnum.hpp @@ -0,0 +1,71 @@ +/// +/// JVariant_SomeEnum_SomeOtherEnum.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © 2025 Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include + +#include "SomeEnum.hpp" +#include "SomeOtherEnum.hpp" +#include +#include "JSomeEnum.hpp" +#include "JSomeOtherEnum.hpp" + +namespace margelo::nitro::test { + + using namespace facebook; + + /** + * The C++ JNI bridge between the C++ std::variant and the Java class "Variant_SomeEnum_SomeOtherEnum". + */ + class JVariant_SomeEnum_SomeOtherEnum: public jni::JavaClass { + public: + static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/test/Variant_SomeEnum_SomeOtherEnum;"; + + static jni::local_ref create_0(jni::alias_ref value) { + static const auto method = javaClassStatic()->getStaticMethod)>("create"); + return method(javaClassStatic(), value); + } + static jni::local_ref create_1(jni::alias_ref value) { + static const auto method = javaClassStatic()->getStaticMethod)>("create"); + return method(javaClassStatic(), value); + } + + static jni::local_ref fromCpp(const std::variant& variant) { + switch (variant.index()) { + case 0: return create_0(JSomeEnum::fromCpp(std::get<0>(variant))); + case 1: return create_1(JSomeOtherEnum::fromCpp(std::get<1>(variant))); + default: throw std::invalid_argument("Variant holds unknown index! (" + std::to_string(variant.index()) + ")"); + } + } + + [[nodiscard]] std::variant toCpp() const; + }; + + namespace JVariant_SomeEnum_SomeOtherEnum_impl { + class First: public jni::JavaClass { + public: + static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/test/Variant_SomeEnum_SomeOtherEnum$First;"; + + [[nodiscard]] jni::local_ref getValue() const { + static const auto field = javaClassStatic()->getField("value"); + return getFieldValue(field); + } + }; + + class Second: public jni::JavaClass { + public: + static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/test/Variant_SomeEnum_SomeOtherEnum$Second;"; + + [[nodiscard]] jni::local_ref getValue() const { + static const auto field = javaClassStatic()->getField("value"); + return getFieldValue(field); + } + }; + } // namespace JVariant_SomeEnum_SomeOtherEnum_impl +} // namespace margelo::nitro::test diff --git a/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridTestObjectSwiftKotlinSpec.kt b/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridTestObjectSwiftKotlinSpec.kt index 98465d682..c3b69bcee 100644 --- a/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridTestObjectSwiftKotlinSpec.kt +++ b/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridTestObjectSwiftKotlinSpec.kt @@ -518,6 +518,26 @@ abstract class HybridTestObjectSwiftKotlinSpec: HybridObject() { @Keep abstract fun getVariantWeirdNumbersEnum(variant: Variant_Boolean_WeirdNumbersEnum): Variant_Boolean_WeirdNumbersEnum + @DoNotStrip + @Keep + abstract fun getVariantSomeEnum(variant: Variant_Boolean_SomeEnum): Variant_Boolean_SomeEnum + + @DoNotStrip + @Keep + abstract fun getVariantMultipleEnums(variant: Variant_SomeEnum_SomeOtherEnum): Variant_SomeEnum_SomeOtherEnum + + @DoNotStrip + @Keep + abstract fun getVariantStringAndEnum(variant: String): String + + @DoNotStrip + @Keep + abstract fun getVariantThreeTypes(variant: Variant_Boolean_SomeEnum_SomeOtherEnum): Variant_Boolean_SomeEnum_SomeOtherEnum + + @DoNotStrip + @Keep + abstract fun getVariantNumberAndEnum(variant: Variant_SomeEnum_Double): Variant_SomeEnum_Double + @DoNotStrip @Keep abstract fun getVariantObjects(variant: Variant_Car_Person): Variant_Car_Person diff --git a/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/SomeEnum.kt b/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/SomeEnum.kt new file mode 100644 index 000000000..7c23b1e13 --- /dev/null +++ b/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/SomeEnum.kt @@ -0,0 +1,21 @@ +/// +/// SomeEnum.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © 2025 Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.test + +import androidx.annotation.Keep +import com.facebook.proguard.annotations.DoNotStrip + +/** + * Represents the JavaScript enum/union "SomeEnum". + */ +@DoNotStrip +@Keep +enum class SomeEnum(@DoNotStrip @Keep val value: Int) { + FOO(0), + BAR(1); +} diff --git a/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/SomeOtherEnum.kt b/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/SomeOtherEnum.kt new file mode 100644 index 000000000..88a6d76eb --- /dev/null +++ b/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/SomeOtherEnum.kt @@ -0,0 +1,21 @@ +/// +/// SomeOtherEnum.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © 2025 Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.test + +import androidx.annotation.Keep +import com.facebook.proguard.annotations.DoNotStrip + +/** + * Represents the JavaScript enum/union "SomeOtherEnum". + */ +@DoNotStrip +@Keep +enum class SomeOtherEnum(@DoNotStrip @Keep val value: Int) { + BAZ(0), + QUX(1); +} diff --git a/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/Variant_Boolean_SomeEnum.kt b/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/Variant_Boolean_SomeEnum.kt new file mode 100644 index 000000000..42145241e --- /dev/null +++ b/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/Variant_Boolean_SomeEnum.kt @@ -0,0 +1,59 @@ +/// +/// Variant_Boolean_SomeEnum.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © 2025 Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.test + +import com.facebook.proguard.annotations.DoNotStrip + + +/** + * Represents the TypeScript variant "Boolean | SomeEnum". + */ +@Suppress("ClassName") +@DoNotStrip +sealed class Variant_Boolean_SomeEnum { + @DoNotStrip + data class First(@DoNotStrip val value: Boolean): Variant_Boolean_SomeEnum() + @DoNotStrip + data class Second(@DoNotStrip val value: SomeEnum): Variant_Boolean_SomeEnum() + + @Deprecated("getAs() is not type-safe. Use fold/asFirstOrNull/asSecondOrNull instead.", level = DeprecationLevel.ERROR) + inline fun getAs(): T? = when (this) { + is First -> value as? T + is Second -> value as? T + } + + val isFirst: Boolean + get() = this is First + val isSecond: Boolean + get() = this is Second + + fun asFirstOrNull(): Boolean? { + val value = (this as? First)?.value ?: return null + return value + } + fun asSecondOrNull(): SomeEnum? { + val value = (this as? Second)?.value ?: return null + return value + } + + inline fun match(first: (Boolean) -> R, second: (SomeEnum) -> R): R { + return when (this) { + is First -> first(value) + is Second -> second(value) + } + } + + companion object { + @JvmStatic + @DoNotStrip + fun create(value: Boolean): Variant_Boolean_SomeEnum = First(value) + @JvmStatic + @DoNotStrip + fun create(value: SomeEnum): Variant_Boolean_SomeEnum = Second(value) + } +} diff --git a/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/Variant_Boolean_SomeEnum_SomeOtherEnum.kt b/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/Variant_Boolean_SomeEnum_SomeOtherEnum.kt new file mode 100644 index 000000000..9bd765115 --- /dev/null +++ b/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/Variant_Boolean_SomeEnum_SomeOtherEnum.kt @@ -0,0 +1,72 @@ +/// +/// Variant_Boolean_SomeEnum_SomeOtherEnum.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © 2025 Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.test + +import com.facebook.proguard.annotations.DoNotStrip + + +/** + * Represents the TypeScript variant "Boolean | SomeEnum | SomeOtherEnum". + */ +@Suppress("ClassName") +@DoNotStrip +sealed class Variant_Boolean_SomeEnum_SomeOtherEnum { + @DoNotStrip + data class First(@DoNotStrip val value: Boolean): Variant_Boolean_SomeEnum_SomeOtherEnum() + @DoNotStrip + data class Second(@DoNotStrip val value: SomeEnum): Variant_Boolean_SomeEnum_SomeOtherEnum() + @DoNotStrip + data class Third(@DoNotStrip val value: SomeOtherEnum): Variant_Boolean_SomeEnum_SomeOtherEnum() + + @Deprecated("getAs() is not type-safe. Use fold/asFirstOrNull/asSecondOrNull instead.", level = DeprecationLevel.ERROR) + inline fun getAs(): T? = when (this) { + is First -> value as? T + is Second -> value as? T + is Third -> value as? T + } + + val isFirst: Boolean + get() = this is First + val isSecond: Boolean + get() = this is Second + val isThird: Boolean + get() = this is Third + + fun asFirstOrNull(): Boolean? { + val value = (this as? First)?.value ?: return null + return value + } + fun asSecondOrNull(): SomeEnum? { + val value = (this as? Second)?.value ?: return null + return value + } + fun asThirdOrNull(): SomeOtherEnum? { + val value = (this as? Third)?.value ?: return null + return value + } + + inline fun match(first: (Boolean) -> R, second: (SomeEnum) -> R, third: (SomeOtherEnum) -> R): R { + return when (this) { + is First -> first(value) + is Second -> second(value) + is Third -> third(value) + } + } + + companion object { + @JvmStatic + @DoNotStrip + fun create(value: Boolean): Variant_Boolean_SomeEnum_SomeOtherEnum = First(value) + @JvmStatic + @DoNotStrip + fun create(value: SomeEnum): Variant_Boolean_SomeEnum_SomeOtherEnum = Second(value) + @JvmStatic + @DoNotStrip + fun create(value: SomeOtherEnum): Variant_Boolean_SomeEnum_SomeOtherEnum = Third(value) + } +} diff --git a/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/Variant_SomeEnum_Double.kt b/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/Variant_SomeEnum_Double.kt new file mode 100644 index 000000000..56a3edcbc --- /dev/null +++ b/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/Variant_SomeEnum_Double.kt @@ -0,0 +1,59 @@ +/// +/// Variant_SomeEnum_Double.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © 2025 Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.test + +import com.facebook.proguard.annotations.DoNotStrip + + +/** + * Represents the TypeScript variant "SomeEnum | Double". + */ +@Suppress("ClassName") +@DoNotStrip +sealed class Variant_SomeEnum_Double { + @DoNotStrip + data class First(@DoNotStrip val value: SomeEnum): Variant_SomeEnum_Double() + @DoNotStrip + data class Second(@DoNotStrip val value: Double): Variant_SomeEnum_Double() + + @Deprecated("getAs() is not type-safe. Use fold/asFirstOrNull/asSecondOrNull instead.", level = DeprecationLevel.ERROR) + inline fun getAs(): T? = when (this) { + is First -> value as? T + is Second -> value as? T + } + + val isFirst: Boolean + get() = this is First + val isSecond: Boolean + get() = this is Second + + fun asFirstOrNull(): SomeEnum? { + val value = (this as? First)?.value ?: return null + return value + } + fun asSecondOrNull(): Double? { + val value = (this as? Second)?.value ?: return null + return value + } + + inline fun match(first: (SomeEnum) -> R, second: (Double) -> R): R { + return when (this) { + is First -> first(value) + is Second -> second(value) + } + } + + companion object { + @JvmStatic + @DoNotStrip + fun create(value: SomeEnum): Variant_SomeEnum_Double = First(value) + @JvmStatic + @DoNotStrip + fun create(value: Double): Variant_SomeEnum_Double = Second(value) + } +} diff --git a/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/Variant_SomeEnum_SomeOtherEnum.kt b/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/Variant_SomeEnum_SomeOtherEnum.kt new file mode 100644 index 000000000..01ce99ca9 --- /dev/null +++ b/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/Variant_SomeEnum_SomeOtherEnum.kt @@ -0,0 +1,59 @@ +/// +/// Variant_SomeEnum_SomeOtherEnum.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © 2025 Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.test + +import com.facebook.proguard.annotations.DoNotStrip + + +/** + * Represents the TypeScript variant "SomeEnum | SomeOtherEnum". + */ +@Suppress("ClassName") +@DoNotStrip +sealed class Variant_SomeEnum_SomeOtherEnum { + @DoNotStrip + data class First(@DoNotStrip val value: SomeEnum): Variant_SomeEnum_SomeOtherEnum() + @DoNotStrip + data class Second(@DoNotStrip val value: SomeOtherEnum): Variant_SomeEnum_SomeOtherEnum() + + @Deprecated("getAs() is not type-safe. Use fold/asFirstOrNull/asSecondOrNull instead.", level = DeprecationLevel.ERROR) + inline fun getAs(): T? = when (this) { + is First -> value as? T + is Second -> value as? T + } + + val isFirst: Boolean + get() = this is First + val isSecond: Boolean + get() = this is Second + + fun asFirstOrNull(): SomeEnum? { + val value = (this as? First)?.value ?: return null + return value + } + fun asSecondOrNull(): SomeOtherEnum? { + val value = (this as? Second)?.value ?: return null + return value + } + + inline fun match(first: (SomeEnum) -> R, second: (SomeOtherEnum) -> R): R { + return when (this) { + is First -> first(value) + is Second -> second(value) + } + } + + companion object { + @JvmStatic + @DoNotStrip + fun create(value: SomeEnum): Variant_SomeEnum_SomeOtherEnum = First(value) + @JvmStatic + @DoNotStrip + fun create(value: SomeOtherEnum): Variant_SomeEnum_SomeOtherEnum = Second(value) + } +} diff --git a/packages/react-native-nitro-test/nitrogen/generated/ios/NitroTest-Swift-Cxx-Bridge.hpp b/packages/react-native-nitro-test/nitrogen/generated/ios/NitroTest-Swift-Cxx-Bridge.hpp index addd124fb..dfa3dba77 100644 --- a/packages/react-native-nitro-test/nitrogen/generated/ios/NitroTest-Swift-Cxx-Bridge.hpp +++ b/packages/react-native-nitro-test/nitrogen/generated/ios/NitroTest-Swift-Cxx-Bridge.hpp @@ -40,6 +40,10 @@ namespace margelo::nitro::test { struct PartialPerson; } namespace margelo::nitro::test { struct Person; } // Forward declaration of `Powertrain` to properly resolve imports. namespace margelo::nitro::test { enum class Powertrain; } +// Forward declaration of `SomeEnum` to properly resolve imports. +namespace margelo::nitro::test { enum class SomeEnum; } +// Forward declaration of `SomeOtherEnum` to properly resolve imports. +namespace margelo::nitro::test { enum class SomeOtherEnum; } // Forward declaration of `WeirdNumbersEnum` to properly resolve imports. namespace margelo::nitro::test { enum class WeirdNumbersEnum; } // Forward declaration of `WrappedJsStruct` to properly resolve imports. @@ -74,6 +78,8 @@ namespace NitroTest { class HybridTestViewSpec_cxx; } #include "PartialPerson.hpp" #include "Person.hpp" #include "Powertrain.hpp" +#include "SomeEnum.hpp" +#include "SomeOtherEnum.hpp" #include "WeirdNumbersEnum.hpp" #include "WrappedJsStruct.hpp" #include @@ -1256,6 +1262,128 @@ namespace margelo::nitro::test::bridge::swift { return std__variant_bool__WeirdNumbersEnum_(value); } + // pragma MARK: std::variant + /** + * Wrapper struct for `std::variant`. + * std::variant cannot be used in Swift because of a Swift bug. + * Not even specializing it works. So we create a wrapper struct. + */ + struct std__variant_bool__SomeEnum_ { + std::variant variant; + std__variant_bool__SomeEnum_(std::variant variant): variant(variant) { } + operator std::variant() const noexcept { + return variant; + } + inline size_t index() const noexcept { + return variant.index(); + } + inline bool get_0() const noexcept { + return std::get<0>(variant); + } + inline SomeEnum get_1() const noexcept { + return std::get<1>(variant); + } + }; + inline std__variant_bool__SomeEnum_ create_std__variant_bool__SomeEnum_(bool value) noexcept { + return std__variant_bool__SomeEnum_(value); + } + inline std__variant_bool__SomeEnum_ create_std__variant_bool__SomeEnum_(SomeEnum value) noexcept { + return std__variant_bool__SomeEnum_(value); + } + + // pragma MARK: std::variant + /** + * Wrapper struct for `std::variant`. + * std::variant cannot be used in Swift because of a Swift bug. + * Not even specializing it works. So we create a wrapper struct. + */ + struct std__variant_SomeEnum__SomeOtherEnum_ { + std::variant variant; + std__variant_SomeEnum__SomeOtherEnum_(std::variant variant): variant(variant) { } + operator std::variant() const noexcept { + return variant; + } + inline size_t index() const noexcept { + return variant.index(); + } + inline SomeEnum get_0() const noexcept { + return std::get<0>(variant); + } + inline SomeOtherEnum get_1() const noexcept { + return std::get<1>(variant); + } + }; + inline std__variant_SomeEnum__SomeOtherEnum_ create_std__variant_SomeEnum__SomeOtherEnum_(SomeEnum value) noexcept { + return std__variant_SomeEnum__SomeOtherEnum_(value); + } + inline std__variant_SomeEnum__SomeOtherEnum_ create_std__variant_SomeEnum__SomeOtherEnum_(SomeOtherEnum value) noexcept { + return std__variant_SomeEnum__SomeOtherEnum_(value); + } + + // pragma MARK: std::variant + /** + * Wrapper struct for `std::variant`. + * std::variant cannot be used in Swift because of a Swift bug. + * Not even specializing it works. So we create a wrapper struct. + */ + struct std__variant_bool__SomeEnum__SomeOtherEnum_ { + std::variant variant; + std__variant_bool__SomeEnum__SomeOtherEnum_(std::variant variant): variant(variant) { } + operator std::variant() const noexcept { + return variant; + } + inline size_t index() const noexcept { + return variant.index(); + } + inline bool get_0() const noexcept { + return std::get<0>(variant); + } + inline SomeEnum get_1() const noexcept { + return std::get<1>(variant); + } + inline SomeOtherEnum get_2() const noexcept { + return std::get<2>(variant); + } + }; + inline std__variant_bool__SomeEnum__SomeOtherEnum_ create_std__variant_bool__SomeEnum__SomeOtherEnum_(bool value) noexcept { + return std__variant_bool__SomeEnum__SomeOtherEnum_(value); + } + inline std__variant_bool__SomeEnum__SomeOtherEnum_ create_std__variant_bool__SomeEnum__SomeOtherEnum_(SomeEnum value) noexcept { + return std__variant_bool__SomeEnum__SomeOtherEnum_(value); + } + inline std__variant_bool__SomeEnum__SomeOtherEnum_ create_std__variant_bool__SomeEnum__SomeOtherEnum_(SomeOtherEnum value) noexcept { + return std__variant_bool__SomeEnum__SomeOtherEnum_(value); + } + + // pragma MARK: std::variant + /** + * Wrapper struct for `std::variant`. + * std::variant cannot be used in Swift because of a Swift bug. + * Not even specializing it works. So we create a wrapper struct. + */ + struct std__variant_SomeEnum__double_ { + std::variant variant; + std__variant_SomeEnum__double_(std::variant variant): variant(variant) { } + operator std::variant() const noexcept { + return variant; + } + inline size_t index() const noexcept { + return variant.index(); + } + inline SomeEnum get_0() const noexcept { + return std::get<0>(variant); + } + inline double get_1() const noexcept { + return std::get<1>(variant); + } + }; + inline std__variant_SomeEnum__double_ create_std__variant_SomeEnum__double_(SomeEnum value) noexcept { + return std__variant_SomeEnum__double_(value); + } + inline std__variant_SomeEnum__double_ create_std__variant_SomeEnum__double_(double value) noexcept { + return std__variant_SomeEnum__double_(value); + } + // pragma MARK: std::variant /** * Wrapper struct for `std::variant`. @@ -1817,6 +1945,42 @@ namespace margelo::nitro::test::bridge::swift { return Result>::withError(error); } + // pragma MARK: Result> + using Result_std__variant_bool__SomeEnum__ = Result>; + inline Result_std__variant_bool__SomeEnum__ create_Result_std__variant_bool__SomeEnum__(const std::variant& value) noexcept { + return Result>::withValue(value); + } + inline Result_std__variant_bool__SomeEnum__ create_Result_std__variant_bool__SomeEnum__(const std::exception_ptr& error) noexcept { + return Result>::withError(error); + } + + // pragma MARK: Result> + using Result_std__variant_SomeEnum__SomeOtherEnum__ = Result>; + inline Result_std__variant_SomeEnum__SomeOtherEnum__ create_Result_std__variant_SomeEnum__SomeOtherEnum__(const std::variant& value) noexcept { + return Result>::withValue(value); + } + inline Result_std__variant_SomeEnum__SomeOtherEnum__ create_Result_std__variant_SomeEnum__SomeOtherEnum__(const std::exception_ptr& error) noexcept { + return Result>::withError(error); + } + + // pragma MARK: Result> + using Result_std__variant_bool__SomeEnum__SomeOtherEnum__ = Result>; + inline Result_std__variant_bool__SomeEnum__SomeOtherEnum__ create_Result_std__variant_bool__SomeEnum__SomeOtherEnum__(const std::variant& value) noexcept { + return Result>::withValue(value); + } + inline Result_std__variant_bool__SomeEnum__SomeOtherEnum__ create_Result_std__variant_bool__SomeEnum__SomeOtherEnum__(const std::exception_ptr& error) noexcept { + return Result>::withError(error); + } + + // pragma MARK: Result> + using Result_std__variant_SomeEnum__double__ = Result>; + inline Result_std__variant_SomeEnum__double__ create_Result_std__variant_SomeEnum__double__(const std::variant& value) noexcept { + return Result>::withValue(value); + } + inline Result_std__variant_SomeEnum__double__ create_Result_std__variant_SomeEnum__double__(const std::exception_ptr& error) noexcept { + return Result>::withError(error); + } + // pragma MARK: Result> using Result_std__variant_Car__Person__ = Result>; inline Result_std__variant_Car__Person__ create_Result_std__variant_Car__Person__(const std::variant& value) noexcept { diff --git a/packages/react-native-nitro-test/nitrogen/generated/ios/NitroTest-Swift-Cxx-Umbrella.hpp b/packages/react-native-nitro-test/nitrogen/generated/ios/NitroTest-Swift-Cxx-Umbrella.hpp index b5e51455b..d4d9b5d83 100644 --- a/packages/react-native-nitro-test/nitrogen/generated/ios/NitroTest-Swift-Cxx-Umbrella.hpp +++ b/packages/react-native-nitro-test/nitrogen/generated/ios/NitroTest-Swift-Cxx-Umbrella.hpp @@ -44,6 +44,10 @@ namespace margelo::nitro::test { struct Person; } namespace margelo::nitro::test { enum class Powertrain; } // Forward declaration of `SecondMapWrapper` to properly resolve imports. namespace margelo::nitro::test { struct SecondMapWrapper; } +// Forward declaration of `SomeEnum` to properly resolve imports. +namespace margelo::nitro::test { enum class SomeEnum; } +// Forward declaration of `SomeOtherEnum` to properly resolve imports. +namespace margelo::nitro::test { enum class SomeOtherEnum; } // Forward declaration of `WeirdNumbersEnum` to properly resolve imports. namespace margelo::nitro::test { enum class WeirdNumbersEnum; } // Forward declaration of `WrappedJsStruct` to properly resolve imports. @@ -67,6 +71,8 @@ namespace margelo::nitro::test { struct WrappedJsStruct; } #include "Person.hpp" #include "Powertrain.hpp" #include "SecondMapWrapper.hpp" +#include "SomeEnum.hpp" +#include "SomeOtherEnum.hpp" #include "WeirdNumbersEnum.hpp" #include "WrappedJsStruct.hpp" #include diff --git a/packages/react-native-nitro-test/nitrogen/generated/ios/c++/HybridTestObjectSwiftKotlinSpecSwift.hpp b/packages/react-native-nitro-test/nitrogen/generated/ios/c++/HybridTestObjectSwiftKotlinSpecSwift.hpp index 9ee0f9c18..3aa9a473c 100644 --- a/packages/react-native-nitro-test/nitrogen/generated/ios/c++/HybridTestObjectSwiftKotlinSpecSwift.hpp +++ b/packages/react-native-nitro-test/nitrogen/generated/ios/c++/HybridTestObjectSwiftKotlinSpecSwift.hpp @@ -42,6 +42,10 @@ namespace margelo::nitro::test { struct OptionalWrapper; } namespace margelo::nitro::test { struct OptionalCallback; } // Forward declaration of `WeirdNumbersEnum` to properly resolve imports. namespace margelo::nitro::test { enum class WeirdNumbersEnum; } +// Forward declaration of `SomeEnum` to properly resolve imports. +namespace margelo::nitro::test { enum class SomeEnum; } +// Forward declaration of `SomeOtherEnum` to properly resolve imports. +namespace margelo::nitro::test { enum class SomeOtherEnum; } // Forward declaration of `HybridBaseSpec` to properly resolve imports. namespace margelo::nitro::test { class HybridBaseSpec; } // Forward declaration of `HybridTestViewSpec` to properly resolve imports. @@ -79,6 +83,8 @@ namespace margelo::nitro::test { struct ExternalObjectStruct; } #include "OptionalWrapper.hpp" #include "OptionalCallback.hpp" #include "WeirdNumbersEnum.hpp" +#include "SomeEnum.hpp" +#include "SomeOtherEnum.hpp" #include "HybridBaseSpec.hpp" #include "HybridTestViewSpec.hpp" #include @@ -812,6 +818,46 @@ namespace margelo::nitro::test { auto __value = std::move(__result.value()); return __value; } + inline std::variant getVariantSomeEnum(const std::variant& variant) override { + auto __result = _swiftPart.getVariantSomeEnum(variant); + if (__result.hasError()) [[unlikely]] { + std::rethrow_exception(__result.error()); + } + auto __value = std::move(__result.value()); + return __value; + } + inline std::variant getVariantMultipleEnums(const std::variant& variant) override { + auto __result = _swiftPart.getVariantMultipleEnums(variant); + if (__result.hasError()) [[unlikely]] { + std::rethrow_exception(__result.error()); + } + auto __value = std::move(__result.value()); + return __value; + } + inline std::string getVariantStringAndEnum(const std::string& variant) override { + auto __result = _swiftPart.getVariantStringAndEnum(variant); + if (__result.hasError()) [[unlikely]] { + std::rethrow_exception(__result.error()); + } + auto __value = std::move(__result.value()); + return __value; + } + inline std::variant getVariantThreeTypes(const std::variant& variant) override { + auto __result = _swiftPart.getVariantThreeTypes(variant); + if (__result.hasError()) [[unlikely]] { + std::rethrow_exception(__result.error()); + } + auto __value = std::move(__result.value()); + return __value; + } + inline std::variant getVariantNumberAndEnum(const std::variant& variant) override { + auto __result = _swiftPart.getVariantNumberAndEnum(variant); + if (__result.hasError()) [[unlikely]] { + std::rethrow_exception(__result.error()); + } + auto __value = std::move(__result.value()); + return __value; + } inline std::variant getVariantObjects(const std::variant& variant) override { auto __result = _swiftPart.getVariantObjects(variant); if (__result.hasError()) [[unlikely]] { diff --git a/packages/react-native-nitro-test/nitrogen/generated/ios/swift/HybridTestObjectSwiftKotlinSpec.swift b/packages/react-native-nitro-test/nitrogen/generated/ios/swift/HybridTestObjectSwiftKotlinSpec.swift index b7e531079..2519ba03b 100644 --- a/packages/react-native-nitro-test/nitrogen/generated/ios/swift/HybridTestObjectSwiftKotlinSpec.swift +++ b/packages/react-native-nitro-test/nitrogen/generated/ios/swift/HybridTestObjectSwiftKotlinSpec.swift @@ -105,6 +105,11 @@ public protocol HybridTestObjectSwiftKotlinSpec_protocol: HybridObject { func passVariant(either: Variant_Bool__Double___String__String_Double) throws -> Variant_String_Double func getVariantEnum(variant: Variant_Bool_OldEnum) throws -> Variant_Bool_OldEnum func getVariantWeirdNumbersEnum(variant: Variant_Bool_WeirdNumbersEnum) throws -> Variant_Bool_WeirdNumbersEnum + func getVariantSomeEnum(variant: Variant_Bool_SomeEnum) throws -> Variant_Bool_SomeEnum + func getVariantMultipleEnums(variant: Variant_SomeEnum_SomeOtherEnum) throws -> Variant_SomeEnum_SomeOtherEnum + func getVariantStringAndEnum(variant: String) throws -> String + func getVariantThreeTypes(variant: Variant_Bool_SomeEnum_SomeOtherEnum) throws -> Variant_Bool_SomeEnum_SomeOtherEnum + func getVariantNumberAndEnum(variant: Variant_SomeEnum_Double) throws -> Variant_SomeEnum_Double func getVariantObjects(variant: Variant_Car_Person) throws -> Variant_Car_Person func passNamedVariant(variant: NamedVariant) throws -> NamedVariant func passAllEmptyObjectVariant(variant: Variant__any_HybridBaseSpec__OptionalWrapper) throws -> Variant__any_HybridBaseSpec__OptionalWrapper diff --git a/packages/react-native-nitro-test/nitrogen/generated/ios/swift/HybridTestObjectSwiftKotlinSpec_cxx.swift b/packages/react-native-nitro-test/nitrogen/generated/ios/swift/HybridTestObjectSwiftKotlinSpec_cxx.swift index da7bae85d..64eedfd2d 100644 --- a/packages/react-native-nitro-test/nitrogen/generated/ios/swift/HybridTestObjectSwiftKotlinSpec_cxx.swift +++ b/packages/react-native-nitro-test/nitrogen/generated/ios/swift/HybridTestObjectSwiftKotlinSpec_cxx.swift @@ -1986,6 +1986,147 @@ open class HybridTestObjectSwiftKotlinSpec_cxx { } } + @inline(__always) + public final func getVariantSomeEnum(variant: bridge.std__variant_bool__SomeEnum_) -> bridge.Result_std__variant_bool__SomeEnum__ { + do { + let __result = try self.__implementation.getVariantSomeEnum(variant: { () -> Variant_Bool_SomeEnum in + let __variant = variant + switch __variant.index() { + case 0: + let __actual = __variant.get_0() + return .first(__actual) + case 1: + let __actual = __variant.get_1() + return .second(__actual) + default: + fatalError("Variant can never have index \(__variant.index())!") + } + }()) + let __resultCpp = { () -> bridge.std__variant_bool__SomeEnum_ in + switch __result { + case .first(let __value): + return bridge.create_std__variant_bool__SomeEnum_(__value) + case .second(let __value): + return bridge.create_std__variant_bool__SomeEnum_(__value) + } + }().variant + return bridge.create_Result_std__variant_bool__SomeEnum__(__resultCpp) + } catch (let __error) { + let __exceptionPtr = __error.toCpp() + return bridge.create_Result_std__variant_bool__SomeEnum__(__exceptionPtr) + } + } + + @inline(__always) + public final func getVariantMultipleEnums(variant: bridge.std__variant_SomeEnum__SomeOtherEnum_) -> bridge.Result_std__variant_SomeEnum__SomeOtherEnum__ { + do { + let __result = try self.__implementation.getVariantMultipleEnums(variant: { () -> Variant_SomeEnum_SomeOtherEnum in + let __variant = variant + switch __variant.index() { + case 0: + let __actual = __variant.get_0() + return .first(__actual) + case 1: + let __actual = __variant.get_1() + return .second(__actual) + default: + fatalError("Variant can never have index \(__variant.index())!") + } + }()) + let __resultCpp = { () -> bridge.std__variant_SomeEnum__SomeOtherEnum_ in + switch __result { + case .first(let __value): + return bridge.create_std__variant_SomeEnum__SomeOtherEnum_(__value) + case .second(let __value): + return bridge.create_std__variant_SomeEnum__SomeOtherEnum_(__value) + } + }().variant + return bridge.create_Result_std__variant_SomeEnum__SomeOtherEnum__(__resultCpp) + } catch (let __error) { + let __exceptionPtr = __error.toCpp() + return bridge.create_Result_std__variant_SomeEnum__SomeOtherEnum__(__exceptionPtr) + } + } + + @inline(__always) + public final func getVariantStringAndEnum(variant: std.string) -> bridge.Result_std__string_ { + do { + let __result = try self.__implementation.getVariantStringAndEnum(variant: String(variant)) + let __resultCpp = std.string(__result) + return bridge.create_Result_std__string_(__resultCpp) + } catch (let __error) { + let __exceptionPtr = __error.toCpp() + return bridge.create_Result_std__string_(__exceptionPtr) + } + } + + @inline(__always) + public final func getVariantThreeTypes(variant: bridge.std__variant_bool__SomeEnum__SomeOtherEnum_) -> bridge.Result_std__variant_bool__SomeEnum__SomeOtherEnum__ { + do { + let __result = try self.__implementation.getVariantThreeTypes(variant: { () -> Variant_Bool_SomeEnum_SomeOtherEnum in + let __variant = variant + switch __variant.index() { + case 0: + let __actual = __variant.get_0() + return .first(__actual) + case 1: + let __actual = __variant.get_1() + return .second(__actual) + case 2: + let __actual = __variant.get_2() + return .third(__actual) + default: + fatalError("Variant can never have index \(__variant.index())!") + } + }()) + let __resultCpp = { () -> bridge.std__variant_bool__SomeEnum__SomeOtherEnum_ in + switch __result { + case .first(let __value): + return bridge.create_std__variant_bool__SomeEnum__SomeOtherEnum_(__value) + case .second(let __value): + return bridge.create_std__variant_bool__SomeEnum__SomeOtherEnum_(__value) + case .third(let __value): + return bridge.create_std__variant_bool__SomeEnum__SomeOtherEnum_(__value) + } + }().variant + return bridge.create_Result_std__variant_bool__SomeEnum__SomeOtherEnum__(__resultCpp) + } catch (let __error) { + let __exceptionPtr = __error.toCpp() + return bridge.create_Result_std__variant_bool__SomeEnum__SomeOtherEnum__(__exceptionPtr) + } + } + + @inline(__always) + public final func getVariantNumberAndEnum(variant: bridge.std__variant_SomeEnum__double_) -> bridge.Result_std__variant_SomeEnum__double__ { + do { + let __result = try self.__implementation.getVariantNumberAndEnum(variant: { () -> Variant_SomeEnum_Double in + let __variant = variant + switch __variant.index() { + case 0: + let __actual = __variant.get_0() + return .first(__actual) + case 1: + let __actual = __variant.get_1() + return .second(__actual) + default: + fatalError("Variant can never have index \(__variant.index())!") + } + }()) + let __resultCpp = { () -> bridge.std__variant_SomeEnum__double_ in + switch __result { + case .first(let __value): + return bridge.create_std__variant_SomeEnum__double_(__value) + case .second(let __value): + return bridge.create_std__variant_SomeEnum__double_(__value) + } + }().variant + return bridge.create_Result_std__variant_SomeEnum__double__(__resultCpp) + } catch (let __error) { + let __exceptionPtr = __error.toCpp() + return bridge.create_Result_std__variant_SomeEnum__double__(__exceptionPtr) + } + } + @inline(__always) public final func getVariantObjects(variant: bridge.std__variant_Car__Person_) -> bridge.Result_std__variant_Car__Person__ { do { diff --git a/packages/react-native-nitro-test/nitrogen/generated/ios/swift/SomeEnum.swift b/packages/react-native-nitro-test/nitrogen/generated/ios/swift/SomeEnum.swift new file mode 100644 index 000000000..0920c4aee --- /dev/null +++ b/packages/react-native-nitro-test/nitrogen/generated/ios/swift/SomeEnum.swift @@ -0,0 +1,40 @@ +/// +/// SomeEnum.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © 2025 Marc Rousavy @ Margelo +/// + +/** + * Represents the JS union `SomeEnum`, backed by a C++ enum. + */ +public typealias SomeEnum = margelo.nitro.test.SomeEnum + +public extension SomeEnum { + /** + * Get a SomeEnum for the given String value, or + * return `nil` if the given value was invalid/unknown. + */ + init?(fromString string: String) { + switch string { + case "foo": + self = .foo + case "bar": + self = .bar + default: + return nil + } + } + + /** + * Get the String value this SomeEnum represents. + */ + var stringValue: String { + switch self { + case .foo: + return "foo" + case .bar: + return "bar" + } + } +} diff --git a/packages/react-native-nitro-test/nitrogen/generated/ios/swift/SomeOtherEnum.swift b/packages/react-native-nitro-test/nitrogen/generated/ios/swift/SomeOtherEnum.swift new file mode 100644 index 000000000..66db421fe --- /dev/null +++ b/packages/react-native-nitro-test/nitrogen/generated/ios/swift/SomeOtherEnum.swift @@ -0,0 +1,40 @@ +/// +/// SomeOtherEnum.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © 2025 Marc Rousavy @ Margelo +/// + +/** + * Represents the JS union `SomeOtherEnum`, backed by a C++ enum. + */ +public typealias SomeOtherEnum = margelo.nitro.test.SomeOtherEnum + +public extension SomeOtherEnum { + /** + * Get a SomeOtherEnum for the given String value, or + * return `nil` if the given value was invalid/unknown. + */ + init?(fromString string: String) { + switch string { + case "baz": + self = .baz + case "qux": + self = .qux + default: + return nil + } + } + + /** + * Get the String value this SomeOtherEnum represents. + */ + var stringValue: String { + switch self { + case .baz: + return "baz" + case .qux: + return "qux" + } + } +} diff --git a/packages/react-native-nitro-test/nitrogen/generated/ios/swift/Variant_Bool_SomeEnum.swift b/packages/react-native-nitro-test/nitrogen/generated/ios/swift/Variant_Bool_SomeEnum.swift new file mode 100644 index 000000000..5e31b6f04 --- /dev/null +++ b/packages/react-native-nitro-test/nitrogen/generated/ios/swift/Variant_Bool_SomeEnum.swift @@ -0,0 +1,18 @@ +/// +/// Variant_Bool_SomeEnum.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © 2025 Marc Rousavy @ Margelo +/// + + + +/** + * An Swift enum with associated values representing a Variant/Union type. + * JS type: `boolean | enum` + */ +@frozen +public indirect enum Variant_Bool_SomeEnum { + case first(Bool) + case second(SomeEnum) +} diff --git a/packages/react-native-nitro-test/nitrogen/generated/ios/swift/Variant_Bool_SomeEnum_SomeOtherEnum.swift b/packages/react-native-nitro-test/nitrogen/generated/ios/swift/Variant_Bool_SomeEnum_SomeOtherEnum.swift new file mode 100644 index 000000000..4102a43b3 --- /dev/null +++ b/packages/react-native-nitro-test/nitrogen/generated/ios/swift/Variant_Bool_SomeEnum_SomeOtherEnum.swift @@ -0,0 +1,19 @@ +/// +/// Variant_Bool_SomeEnum_SomeOtherEnum.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © 2025 Marc Rousavy @ Margelo +/// + + + +/** + * An Swift enum with associated values representing a Variant/Union type. + * JS type: `boolean | enum | enum` + */ +@frozen +public indirect enum Variant_Bool_SomeEnum_SomeOtherEnum { + case first(Bool) + case second(SomeEnum) + case third(SomeOtherEnum) +} diff --git a/packages/react-native-nitro-test/nitrogen/generated/ios/swift/Variant_SomeEnum_Double.swift b/packages/react-native-nitro-test/nitrogen/generated/ios/swift/Variant_SomeEnum_Double.swift new file mode 100644 index 000000000..691766dbc --- /dev/null +++ b/packages/react-native-nitro-test/nitrogen/generated/ios/swift/Variant_SomeEnum_Double.swift @@ -0,0 +1,18 @@ +/// +/// Variant_SomeEnum_Double.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © 2025 Marc Rousavy @ Margelo +/// + + + +/** + * An Swift enum with associated values representing a Variant/Union type. + * JS type: `enum | number` + */ +@frozen +public indirect enum Variant_SomeEnum_Double { + case first(SomeEnum) + case second(Double) +} diff --git a/packages/react-native-nitro-test/nitrogen/generated/ios/swift/Variant_SomeEnum_SomeOtherEnum.swift b/packages/react-native-nitro-test/nitrogen/generated/ios/swift/Variant_SomeEnum_SomeOtherEnum.swift new file mode 100644 index 000000000..11569914b --- /dev/null +++ b/packages/react-native-nitro-test/nitrogen/generated/ios/swift/Variant_SomeEnum_SomeOtherEnum.swift @@ -0,0 +1,18 @@ +/// +/// Variant_SomeEnum_SomeOtherEnum.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © 2025 Marc Rousavy @ Margelo +/// + + + +/** + * An Swift enum with associated values representing a Variant/Union type. + * JS type: `enum | enum` + */ +@frozen +public indirect enum Variant_SomeEnum_SomeOtherEnum { + case first(SomeEnum) + case second(SomeOtherEnum) +} diff --git a/packages/react-native-nitro-test/nitrogen/generated/shared/c++/HybridTestObjectCppSpec.cpp b/packages/react-native-nitro-test/nitrogen/generated/shared/c++/HybridTestObjectCppSpec.cpp index f8e98aa15..98e01e091 100644 --- a/packages/react-native-nitro-test/nitrogen/generated/shared/c++/HybridTestObjectCppSpec.cpp +++ b/packages/react-native-nitro-test/nitrogen/generated/shared/c++/HybridTestObjectCppSpec.cpp @@ -126,6 +126,11 @@ namespace margelo::nitro::test { prototype.registerHybridMethod("passVariant", &HybridTestObjectCppSpec::passVariant); prototype.registerHybridMethod("getVariantEnum", &HybridTestObjectCppSpec::getVariantEnum); prototype.registerHybridMethod("getVariantWeirdNumbersEnum", &HybridTestObjectCppSpec::getVariantWeirdNumbersEnum); + prototype.registerHybridMethod("getVariantSomeEnum", &HybridTestObjectCppSpec::getVariantSomeEnum); + prototype.registerHybridMethod("getVariantMultipleEnums", &HybridTestObjectCppSpec::getVariantMultipleEnums); + prototype.registerHybridMethod("getVariantStringAndEnum", &HybridTestObjectCppSpec::getVariantStringAndEnum); + prototype.registerHybridMethod("getVariantThreeTypes", &HybridTestObjectCppSpec::getVariantThreeTypes); + prototype.registerHybridMethod("getVariantNumberAndEnum", &HybridTestObjectCppSpec::getVariantNumberAndEnum); prototype.registerHybridMethod("getVariantObjects", &HybridTestObjectCppSpec::getVariantObjects); prototype.registerHybridMethod("passNamedVariant", &HybridTestObjectCppSpec::passNamedVariant); prototype.registerHybridMethod("passAllEmptyObjectVariant", &HybridTestObjectCppSpec::passAllEmptyObjectVariant); diff --git a/packages/react-native-nitro-test/nitrogen/generated/shared/c++/HybridTestObjectCppSpec.hpp b/packages/react-native-nitro-test/nitrogen/generated/shared/c++/HybridTestObjectCppSpec.hpp index ee95d3ff2..f5fd01fff 100644 --- a/packages/react-native-nitro-test/nitrogen/generated/shared/c++/HybridTestObjectCppSpec.hpp +++ b/packages/react-native-nitro-test/nitrogen/generated/shared/c++/HybridTestObjectCppSpec.hpp @@ -41,6 +41,10 @@ namespace margelo::nitro::test { struct OptionalWrapper; } namespace margelo::nitro::test { struct OptionalCallback; } // Forward declaration of `WeirdNumbersEnum` to properly resolve imports. namespace margelo::nitro::test { enum class WeirdNumbersEnum; } +// Forward declaration of `SomeEnum` to properly resolve imports. +namespace margelo::nitro::test { enum class SomeEnum; } +// Forward declaration of `SomeOtherEnum` to properly resolve imports. +namespace margelo::nitro::test { enum class SomeOtherEnum; } // Forward declaration of `HybridBaseSpec` to properly resolve imports. namespace margelo::nitro::test { class HybridBaseSpec; } // Forward declaration of `HybridTestViewSpec` to properly resolve imports. @@ -79,6 +83,8 @@ namespace margelo::nitro::test { struct ExternalObjectStruct; } #include "OptionalWrapper.hpp" #include "OptionalCallback.hpp" #include "WeirdNumbersEnum.hpp" +#include "SomeEnum.hpp" +#include "SomeOtherEnum.hpp" #include "HybridBaseSpec.hpp" #include "HybridTestViewSpec.hpp" #include @@ -226,6 +232,11 @@ namespace margelo::nitro::test { virtual std::variant passVariant(const std::variant, std::vector, std::string, double>& either) = 0; virtual std::variant getVariantEnum(const std::variant& variant) = 0; virtual std::variant getVariantWeirdNumbersEnum(const std::variant& variant) = 0; + virtual std::variant getVariantSomeEnum(const std::variant& variant) = 0; + virtual std::variant getVariantMultipleEnums(const std::variant& variant) = 0; + virtual std::string getVariantStringAndEnum(const std::string& variant) = 0; + virtual std::variant getVariantThreeTypes(const std::variant& variant) = 0; + virtual std::variant getVariantNumberAndEnum(const std::variant& variant) = 0; virtual std::variant getVariantObjects(const std::variant& variant) = 0; virtual std::variant passNamedVariant(const std::variant& variant) = 0; virtual std::variant, OptionalWrapper> passAllEmptyObjectVariant(const std::variant, OptionalWrapper>& variant) = 0; diff --git a/packages/react-native-nitro-test/nitrogen/generated/shared/c++/HybridTestObjectSwiftKotlinSpec.cpp b/packages/react-native-nitro-test/nitrogen/generated/shared/c++/HybridTestObjectSwiftKotlinSpec.cpp index 4baa35b8f..8ddaeb9e0 100644 --- a/packages/react-native-nitro-test/nitrogen/generated/shared/c++/HybridTestObjectSwiftKotlinSpec.cpp +++ b/packages/react-native-nitro-test/nitrogen/generated/shared/c++/HybridTestObjectSwiftKotlinSpec.cpp @@ -119,6 +119,11 @@ namespace margelo::nitro::test { prototype.registerHybridMethod("passVariant", &HybridTestObjectSwiftKotlinSpec::passVariant); prototype.registerHybridMethod("getVariantEnum", &HybridTestObjectSwiftKotlinSpec::getVariantEnum); prototype.registerHybridMethod("getVariantWeirdNumbersEnum", &HybridTestObjectSwiftKotlinSpec::getVariantWeirdNumbersEnum); + prototype.registerHybridMethod("getVariantSomeEnum", &HybridTestObjectSwiftKotlinSpec::getVariantSomeEnum); + prototype.registerHybridMethod("getVariantMultipleEnums", &HybridTestObjectSwiftKotlinSpec::getVariantMultipleEnums); + prototype.registerHybridMethod("getVariantStringAndEnum", &HybridTestObjectSwiftKotlinSpec::getVariantStringAndEnum); + prototype.registerHybridMethod("getVariantThreeTypes", &HybridTestObjectSwiftKotlinSpec::getVariantThreeTypes); + prototype.registerHybridMethod("getVariantNumberAndEnum", &HybridTestObjectSwiftKotlinSpec::getVariantNumberAndEnum); prototype.registerHybridMethod("getVariantObjects", &HybridTestObjectSwiftKotlinSpec::getVariantObjects); prototype.registerHybridMethod("passNamedVariant", &HybridTestObjectSwiftKotlinSpec::passNamedVariant); prototype.registerHybridMethod("passAllEmptyObjectVariant", &HybridTestObjectSwiftKotlinSpec::passAllEmptyObjectVariant); diff --git a/packages/react-native-nitro-test/nitrogen/generated/shared/c++/HybridTestObjectSwiftKotlinSpec.hpp b/packages/react-native-nitro-test/nitrogen/generated/shared/c++/HybridTestObjectSwiftKotlinSpec.hpp index 20c1b51ff..0d080576c 100644 --- a/packages/react-native-nitro-test/nitrogen/generated/shared/c++/HybridTestObjectSwiftKotlinSpec.hpp +++ b/packages/react-native-nitro-test/nitrogen/generated/shared/c++/HybridTestObjectSwiftKotlinSpec.hpp @@ -39,6 +39,10 @@ namespace margelo::nitro::test { struct OptionalWrapper; } namespace margelo::nitro::test { struct OptionalCallback; } // Forward declaration of `WeirdNumbersEnum` to properly resolve imports. namespace margelo::nitro::test { enum class WeirdNumbersEnum; } +// Forward declaration of `SomeEnum` to properly resolve imports. +namespace margelo::nitro::test { enum class SomeEnum; } +// Forward declaration of `SomeOtherEnum` to properly resolve imports. +namespace margelo::nitro::test { enum class SomeOtherEnum; } // Forward declaration of `HybridBaseSpec` to properly resolve imports. namespace margelo::nitro::test { class HybridBaseSpec; } // Forward declaration of `HybridTestViewSpec` to properly resolve imports. @@ -74,6 +78,8 @@ namespace margelo::nitro::test { struct ExternalObjectStruct; } #include "OptionalWrapper.hpp" #include "OptionalCallback.hpp" #include "WeirdNumbersEnum.hpp" +#include "SomeEnum.hpp" +#include "SomeOtherEnum.hpp" #include "HybridBaseSpec.hpp" #include "HybridTestViewSpec.hpp" #include @@ -214,6 +220,11 @@ namespace margelo::nitro::test { virtual std::variant passVariant(const std::variant, std::vector, std::string, double>& either) = 0; virtual std::variant getVariantEnum(const std::variant& variant) = 0; virtual std::variant getVariantWeirdNumbersEnum(const std::variant& variant) = 0; + virtual std::variant getVariantSomeEnum(const std::variant& variant) = 0; + virtual std::variant getVariantMultipleEnums(const std::variant& variant) = 0; + virtual std::string getVariantStringAndEnum(const std::string& variant) = 0; + virtual std::variant getVariantThreeTypes(const std::variant& variant) = 0; + virtual std::variant getVariantNumberAndEnum(const std::variant& variant) = 0; virtual std::variant getVariantObjects(const std::variant& variant) = 0; virtual std::variant passNamedVariant(const std::variant& variant) = 0; virtual std::variant, OptionalWrapper> passAllEmptyObjectVariant(const std::variant, OptionalWrapper>& variant) = 0; diff --git a/packages/react-native-nitro-test/nitrogen/generated/shared/c++/SomeEnum.hpp b/packages/react-native-nitro-test/nitrogen/generated/shared/c++/SomeEnum.hpp new file mode 100644 index 000000000..77d9ddd8d --- /dev/null +++ b/packages/react-native-nitro-test/nitrogen/generated/shared/c++/SomeEnum.hpp @@ -0,0 +1,76 @@ +/// +/// SomeEnum.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © 2025 Marc Rousavy @ Margelo +/// + +#pragma once + +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif + +namespace margelo::nitro::test { + + /** + * An enum which can be represented as a JavaScript union (SomeEnum). + */ + enum class SomeEnum { + FOO SWIFT_NAME(foo) = 0, + BAR SWIFT_NAME(bar) = 1, + } CLOSED_ENUM; + +} // namespace margelo::nitro::test + +namespace margelo::nitro { + + // C++ SomeEnum <> JS SomeEnum (union) + template <> + struct JSIConverter final { + static inline margelo::nitro::test::SomeEnum fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) { + std::string unionValue = JSIConverter::fromJSI(runtime, arg); + switch (hashString(unionValue.c_str(), unionValue.size())) { + case hashString("foo"): return margelo::nitro::test::SomeEnum::FOO; + case hashString("bar"): return margelo::nitro::test::SomeEnum::BAR; + default: [[unlikely]] + throw std::invalid_argument("Cannot convert \"" + unionValue + "\" to enum SomeEnum - invalid value!"); + } + } + static inline jsi::Value toJSI(jsi::Runtime& runtime, margelo::nitro::test::SomeEnum arg) { + switch (arg) { + case margelo::nitro::test::SomeEnum::FOO: return JSIConverter::toJSI(runtime, "foo"); + case margelo::nitro::test::SomeEnum::BAR: return JSIConverter::toJSI(runtime, "bar"); + default: [[unlikely]] + throw std::invalid_argument("Cannot convert SomeEnum to JS - invalid value: " + + std::to_string(static_cast(arg)) + "!"); + } + } + static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) { + if (!value.isString()) { + return false; + } + std::string unionValue = JSIConverter::fromJSI(runtime, value); + switch (hashString(unionValue.c_str(), unionValue.size())) { + case hashString("foo"): + case hashString("bar"): + return true; + default: + return false; + } + } + }; + +} // namespace margelo::nitro diff --git a/packages/react-native-nitro-test/nitrogen/generated/shared/c++/SomeOtherEnum.hpp b/packages/react-native-nitro-test/nitrogen/generated/shared/c++/SomeOtherEnum.hpp new file mode 100644 index 000000000..f3e9d0c1a --- /dev/null +++ b/packages/react-native-nitro-test/nitrogen/generated/shared/c++/SomeOtherEnum.hpp @@ -0,0 +1,76 @@ +/// +/// SomeOtherEnum.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © 2025 Marc Rousavy @ Margelo +/// + +#pragma once + +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif + +namespace margelo::nitro::test { + + /** + * An enum which can be represented as a JavaScript union (SomeOtherEnum). + */ + enum class SomeOtherEnum { + BAZ SWIFT_NAME(baz) = 0, + QUX SWIFT_NAME(qux) = 1, + } CLOSED_ENUM; + +} // namespace margelo::nitro::test + +namespace margelo::nitro { + + // C++ SomeOtherEnum <> JS SomeOtherEnum (union) + template <> + struct JSIConverter final { + static inline margelo::nitro::test::SomeOtherEnum fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) { + std::string unionValue = JSIConverter::fromJSI(runtime, arg); + switch (hashString(unionValue.c_str(), unionValue.size())) { + case hashString("baz"): return margelo::nitro::test::SomeOtherEnum::BAZ; + case hashString("qux"): return margelo::nitro::test::SomeOtherEnum::QUX; + default: [[unlikely]] + throw std::invalid_argument("Cannot convert \"" + unionValue + "\" to enum SomeOtherEnum - invalid value!"); + } + } + static inline jsi::Value toJSI(jsi::Runtime& runtime, margelo::nitro::test::SomeOtherEnum arg) { + switch (arg) { + case margelo::nitro::test::SomeOtherEnum::BAZ: return JSIConverter::toJSI(runtime, "baz"); + case margelo::nitro::test::SomeOtherEnum::QUX: return JSIConverter::toJSI(runtime, "qux"); + default: [[unlikely]] + throw std::invalid_argument("Cannot convert SomeOtherEnum to JS - invalid value: " + + std::to_string(static_cast(arg)) + "!"); + } + } + static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) { + if (!value.isString()) { + return false; + } + std::string unionValue = JSIConverter::fromJSI(runtime, value); + switch (hashString(unionValue.c_str(), unionValue.size())) { + case hashString("baz"): + case hashString("qux"): + return true; + default: + return false; + } + } + }; + +} // namespace margelo::nitro diff --git a/packages/react-native-nitro-test/src/specs/TestObject.nitro.ts b/packages/react-native-nitro-test/src/specs/TestObject.nitro.ts index ddbc2cbfb..35f4f2fef 100644 --- a/packages/react-native-nitro-test/src/specs/TestObject.nitro.ts +++ b/packages/react-native-nitro-test/src/specs/TestObject.nitro.ts @@ -23,6 +23,12 @@ export type NamedVariant = string | Car // This one is string-backed. export type Powertrain = 'electric' | 'gas' | 'hybrid' +// Another string union used to test boolean | StringEnum variants +export type SomeEnum = 'foo' | 'bar' + +// Another string union used to test variants consisting of multiple string unions +export type SomeOtherEnum = 'baz' | 'qux' + // A classic TypeScript enum also becomes an `enum` in C++. // This one is number-backed. export enum OldEnum { @@ -252,6 +258,15 @@ interface SharedTestObjectProps { getVariantWeirdNumbersEnum( variant: WeirdNumbersEnum | boolean ): WeirdNumbersEnum | boolean + getVariantSomeEnum(variant: boolean | SomeEnum): boolean | SomeEnum + getVariantMultipleEnums( + variant: SomeEnum | SomeOtherEnum + ): SomeEnum | SomeOtherEnum + getVariantStringAndEnum(variant: string | SomeEnum): string | SomeEnum + getVariantThreeTypes( + variant: boolean | SomeEnum | SomeOtherEnum + ): boolean | SomeEnum | SomeOtherEnum + getVariantNumberAndEnum(variant: number | SomeEnum): number | SomeEnum getVariantObjects(variant: Person | Car): Person | Car passNamedVariant(variant: NamedVariant): NamedVariant passAllEmptyObjectVariant(