jhugman / uniffi-bindgen-react-native

A uniffi bindings generator for calling Rust from react-native
Other
0 stars 0 forks source link

Allow enum variant names that collide with existing types #70

Closed jhugman closed 3 weeks ago

jhugman commented 3 weeks ago

According to The Big O of Code Reviews, this is a O(n) change.

This small PR tweaks the Variant classes for our typescript version of Tagged Enums, to allow Variants to have names of existing types.

For example, it's not uncommon for Rust programs to have enums constructed like so:

struct Dog {}
struct Cat {}

enum Animal {
  Dog(Dog),
  Cat(Cat),
}

The way we've modeled tagged enums are with a frozen object containing a class for each Variant.

So this would translate to:

type Dog = …; // Dog defined elsewhere
type Cat = …;

const Animal = (() => {
    class Dog {
        constructor(public value: Dog) {
            // This Dog value is the wrong type!
            // value is the type of the Variant class.
        }
    }
    class Cat {
        constructor(public value: Cat) {}
    }
    return Object.freeze({ Dog, Cat });
})();

This commit changes the naming of the Variant class:

type Dog = …; // Dog defined elsewhere
type Cat = …;

const Animal = (() => {
    class Dog_ {
        constructor(public value: Dog) {
            // There is no variant class called Dog yet, just Dog_,
            // so value is the correct type.
        }
    }
    class Cat_ {
        constructor(public value: Cat) {}
    }
    // We rename the Dog_ variant class as Dog here,
    // so the only way to access this class is via Animal.Dog.
    return Object.freeze({ Dog: Dog_, Cat: Cat_ });
})();