tjjfvi/subshape

Implicitly-initialized Number Enum Codecs

Closed this issue · 3 comments

PR #14 contains a basic implementation of a codec for implicitly-initialized number enums. Aka.

import * as s from "scale-combinators";

enum Creature {
  SlowLoris,
  Elephant,
  OrchidMantis
}

const creatureCodec = s.orderedNumEnum(Creature);

This codec can then be used to encode and decode (thanks to the implicitly-assigned numbers aligning with u8-represented discriminants).

const encoded = creatureCodec.encode(Creature.OrchidMantis);
const decoded = creatureCodec.decode(encoded); // `Creature.OrchidMantis`

I'm wondering whether this is a mistake. Enums are "soft deprecated" by the TS team. Yes, they're not going anywhere. But no, they are not a language feature to "lean into." Moreover, we cannot appropriately constrain the type param of s.orderedNumEnum. One could supply an invalid enum (for instance, one with un-ordered keys) and only experience an error at runtime.

What is to be done?

I'm unclear as to why this need special handling at all. The definition of orderedNumEnum simply delegates to u8, except for roundtripping through (enum_ as any)[(enum_ as any)[value]] (which afaik is always equivalent to value?).

Thus, it seems that creatureCodec could be defined simply as s.u8 as Codec<Creature>. While this is somewhat unattractive, I don't think taxing enums slightly is a problem, given their soft deprecation.

I would thus be in favor of removing orderedNumEnum and recommending the use of s.u8 as Codec<MyEnum> instead.

Very good point––would you feel the same if there was a decent way to model the constraint of ordered number enums? I suppose the soft deprecation makes this codec unruly in the first place.

As it is today, I agree: let's remove this codec :)

Very good point––would you feel the same if there was a decent way to model the constraint of ordered number enums? I suppose the soft deprecation makes this codec unruly in the first place.

I'm not sure, as I do not understand why such a restriction is necessary.

As it is today, I agree: let's remove this codec :)

Great, I'll submit a PR shortly.