Poor man's implementation of Algebraic Data Types in PHP.
Also known as an enum with an associated value in other languages like Swift or Rust.
Install with composer at krak/adt
<?phpuseKrak\ADT\ADT;
/** * @method static Upc upc(int $numberSystem, int $manufacturer, int $product, int $check) * @method static QrCode qrCode(string $productCode) */abstractclass Barcode extendsADT {
publicstaticfunctiontypes(): array {
return [Upc::class, QrCode::class];
}
}
finalclass Upc extends Barcode {
public$numberSystem;
public$manufacturer;
public$product;
public$check;
publicfunction__construct(int$numberSystem, int$manufacturer, int$product, int$check) {
$this->numberSystem = $numberSystem;
$this->manufacturer = $manufacturer;
$this->product = $product;
$this->check = $check;
}
}
finalclass QrCode extends Barcode {
public$productCode;
publicfunction__construct(string$productCode) {
$this->productCode = $productCode;
}
}
$barcode = newQrCode('abc123');
// requires that all cases are set or exception is thrown$oneOrTwo = $barcode->match([
Upc::class => function(Upc$upc) { return1;},
QrCode::class => function(QrCode$qrCode) { return2; },
]);
// allow a default value$oneOrNull = $barcode->matchWithDefault([
Upc::class => function(Upc$upc) { return1; }
]);
// return static values$threeOrFour = $barcode->match([
Upc::class => 3,
QrCode::class => 4,
]);
// static constructors$qrCode = Barcode::qrCode('abc123');With the example above, if you try to create a QrCode or Upc before ever referencing the Barcode class, you'll likely get a file not found when using composer's psr-4 autoloader.
You can get around this a few ways:
Utilize class mapping
Include the enum class file in the composer autoload.files section (something like php-inc could make that easier)
Utilize static constructors provided by the base ADT class:
<?php$upc = Barcode::upc(1, 2, 3, 4); $qrCode = Barcode::qrCode('abc123');
Tests are run via make test and are stored in the test directory. We use peridot for testing.