Type ‣ Enum ᴾᴴᴾ - chung-leong/zigar GitHub Wiki

JavaScript | PHP


In the Zig language, an enum is a set of named integers. They are represented as unique objects in PHP.

const std = @import("std");

pub const Pet = enum { dog, cat, dragon };

pub fn print(pet: Pet) void {
    std.debug.print("pet = {s}\n", .{@tagName(pet)});
}
<?php

$m = zigar_use(__DIR__ . '/enum-example-1.zig');

echo gettype($m->Pet->dog), "\n";
$m->print($m->Pet->dog);
$m->print($m->Pet->cat);

object
pet = dog
pet = cat

Type conversion

string and number are casted automatically to enums with the corresponding name or value.

<?php

$m = zigar_use(__DIR__ . '/enum-example-1.zig');

$m->print('dog');
$m->print(1);
try {
    $m->print('dingo');
} catch (Exception $e) {
    echo $e->getMessage(), "\n";
}
pet = dog
pet = cat
missing (zig)

Conversely, enums can be converted to string and int using casting operators.

<?php

$m = zigar_use(__DIR__ . '/enum-example-1.zig');

debug_zval_dump((string) $m->Pet->cat);
debug_zval_dump((int) $m->Pet->cat);
string(3) "cat" refcount(4)
int(1)

You can also obtain strings from enums through the special properties __string and __plain.

<?php

$m = zigar_use(__DIR__ . '/enum-example-1.zig');

debug_zval_dump($m->Pet->cat->__string);
debug_zval_dump($m->Pet->cat->__plain);
string(3) "cat" refcount(4)
string(3) "cat" refcount(4)

Non-exhaustive enum

When an enum type is declared to be non-exhaustive, an anonymous enum object would be created every time you employ a number that hasn't been seen before.

const std = @import("std");

pub const JunkFood = enum(u16) {
    hamburger,
    hotdog,
    donut,
    pizza,
    taco,
    _,
};

pub var junk: JunkFood = .donut;

pub fn print() void {
    std.debug.print("junk = {any}\n", .{junk});
}
<?php

$m = zigar_use(__DIR__ . '/enum-example-2.zig');

echo "donut? " . (($m->junk == $m->JunkFood->donut) ? 'yes' : 'no') . "\n";
$m->junk = $m->JunkFood->taco; 
echo "taco? " . (($m->junk == $m->JunkFood->taco) ? 'yes' : 'no') . "\n";
$m->print();
$m->junk = 101;
echo "mystery food #100? " . (($m->junk == $m->JunkFood(100)) ? 'yes' : 'no') . "\n";
echo "mystery food #101? " . (($m->junk == $m->JunkFood(101)) ? 'yes' : 'no') . "\n";
$m->print();
donut? yes
taco? yes
junk = .taco
mystery food #100? no
mystery food #101? yes
junk = @enumFromInt(101)

In packed struct

Enums can appear inside packed structs when they're declared with explicit integer types. An enum with 4 items would need an u2, while an enum with 8 items would need u3.

pub const Pet = enum(u2) { dog, cat, dragon, kangaroo };
pub const Car = enum(u3) { Toyota, Ford, Volkswagen, Tesla, Saab, Fiat, Nissan, Kia };
pub const Computer = enum(u2) { Apple, Dell, Lenovo, HP };

pub const Owner = packed struct {
    pet: Pet,
    car: Car,
    computer: Computer,
};
<?php

$m = zigar_use(__DIR__ . '/enum-example-3.zig');

$owner = new $m->Owner(pet: 'kangaroo', car: 'Toyota', computer: 'Dell');
print_r($owner->__plain);
echo "size = " . strlen($owner->__bytes) . "\n";
stdClass Object
(
    [pet] => kangaroo
    [car] => Toyota
    [computer] => Dell
)
size = 1

Types