Modules

Variant

moduleSource
macOSLinuxWindowswasm

since 0.29.0

#import "Extensions/Variant";

A tagged union whose cases are types, like a Rust enum. A jaic extension, not official Jai: other Jai compilers have no such module, and it may change between jaic releases. See docs/extensions/variant.md.

ExampleOpen in playground ↗
#import "Extensions/Variant";

Number_Or_Text :: Variant(s64, string);

v := variant(Number_Or_Text, 42);       // the case is the type of the value
w: Number_Or_Text;                      // zeroed first case
set(*w, "hi");                          // switches case

if is(v, s64) print("%\n", unwrap(v, s64));

variant_switch(v,                       // every case needs a handler, checked at compile time
    (it: *s64)    { print("number %\n", it.*); },
    (it: *string) { print("text %\n", it.*); },
);
Show moreShow less

A Variant is an index and the bytes of the largest case, aligned for the strictest one. Two cases of one type are not allowed: wrap each in its own struct.

Procedures#

variantsince 0.29.0
($V: Type, value: $T) -> V

Makes a Variant holding value; its type picks the case. variant(Shape, Circle.{ 1 }).

setsince 0.29.0
(v: *$V/Variant, value: $T)

Stores value as the live case, replacing whatever was there without releasing it (see free_variant). It is a compile-time error when T is not a case.

issince 0.29.0
(v: $V/Variant, $T: Type) -> bool

Whether the live case is T.

variant_indexsince 0.29.0
(v: $V/Variant) -> s32

The position of the live case in the type's case list.

getsince 0.29.0
(v: $V/Variant, $T: Type) -> (T, bool)

A copy of the T payload and true; a zeroed T and false when another case is live.

get_pointersince 0.29.0
(v: *$V/Variant, $T: Type) -> *T

A pointer to the T payload inside the variant, or null when another case is live. It stays valid until the variant is set again, freed or moved.

unwrapsince 0.29.0
(v: $V/Variant, $T: Type) -> T

The T payload; asserts that T is the live case.

operator==since 0.29.0
(a: $V/Variant, b: V) -> bool

The live case is equal: the same index and equal payloads. Strings compare by content, arrays element by element, structs member by member; pointers by address.

free_variantsince 0.29.0
(v: *$V/Variant)

Releases the memory the live case owns, with free: strings, resizable arrays (and what their elements own), and the same inside structs and nested variants. Views ([] T) and pointers are not owned and are left alone. Then the variant is zeroed: its first case, zeroed. Only use it on payloads that came from the allocator, not string literals.

(builder: *String_Builder, any: Any, data: *void) -> bool

A Print_Style struct_printer that writes a Variant as its live payload, and passes everything else to the printer that was installed before use_variant_printing (or declines).

()

Makes print("%", variant) write the payload, from now on in this context. Calling it again does nothing; a struct_printer installed earlier still gets the values that are not variants.

is_variant_typesince 0.29.0
(info: *Type_Info) -> bool

Whether info is an instantiation of Variant.

variant_case_infossince 0.29.0
(info: *Type_Info) -> [] *Type_Info

The types of the cases of a Variant, in order.

Types#

Variantstructsince 0.29.0
:: struct

Constants#