Enums and flags

Crow supports enum and flags types mostly for compatibility with C, but you might find them useful in other contexts.

Enum types

An enum type is a type that has only a specified set of possible values.
It's like a union, except that choices can't have any associated value.
This restriction brings with it easy conversion to/from a number or string.

main void() info log "{left opposite}" direction enum(left, right) opposite direction(a direction) match a as left right as right left

match expressions work the same for enums as they do for unions.
Also as with a union, declaring the enum generates functions left and right returning enum values.
The similarity makes it easy to change an enum to union (or vice versa) without breaking too much code.

Conversion

An enum can be converted to a symbol, string, or its backing type (usually nat32).
You can also convert back from a symbol or string, which returns an option of the enum.

main void() info log "{left::direction2.to::nat32}" info log "{left::direction2.to::direction4}" info log "{up::direction4.to::direction2? ?? right}" direction2 enum(left, right) direction4 enum(down, up, left, right) to direction4(a direction2) a.to::symbol.to::(direction4?)! to direction2?(a direction4) a.to::symbol.to

Custom storage type

By default, enums are stored as a nat32, but you can make it a different size of nat, or even an int.

main void() info log "{left.to::nat8}" direction enum(left, right) nat8 storage

You can also choose what integer values are associated with each value. (The default is 0, 1, 2, ... like in C.)
Doing so requires you to use the expanded syntax with one line per enum member.

main void() info log "{left.to::int16}" direction enum int16 storage left = -10 right = 10

Flags types

While enum types store one of the choices, flags types store any number of the choices.

main void() naked clothing = () info log "{naked}" fully-dressed clothing = shirt | pants | shoes info log "{fully-dressed}" info log "{fully-dressed.to::json}" info log "{naked.can-serve}" info log "{shirt.can-serve}" info log "{fully-dressed.can-serve}" clothing flags(shirt, pants, shoes) can-serve bool(a clothing) (shirt | shoes) is-in a

Declaring a flags type declares a function | that gets the union of flags and & that gets the intersection.

As with enums, you can specify the backing type and exactly what value each flag has.
Make sure they are powers of 2.

main void() info log (shirt | shoes).to::nat16.to-binary clothing flags nat16 storage shirt = 0b00100 pants = 0b01000 shoes = 0b10000