Skip to content

Support exhaustiveness checks for sealed interfaces implemented by an enum #2

Description

@stof
#[Sealed(permits: [ColorFormatEnum::class, SpanColorFormat::class])]
interface ColorFormat
{
}


enum ColorFormatEnum implements ColorFormat
{
    /**
     * A color defined using the `rgb()` or `rgba()` functions.
     */
    case rgbFunction;
    /**
     * A color defined using the `hsl()` or `hsla()` functions.
     */
    case hslFunction;
}

final class SpanColorFormat implements ColorFormat
{
    private readonly string $original;

    public function __construct(string $original)
    {
        $this->original = $original;
    }

    public function getOriginal(): string
    {
        return $this->original;
    }
}

interface SassColor {
    public function getFormat(): ColorFormat;
}

function writeColorWithMatch(SassColor $value): void
{
        $format = $value->getFormat();
            match ($format) {
                ColorFormatEnum::rgbFunction => writeRgb($value),
                ColorFormatEnum::hslFunction => writeHsl($value),
                default => write($format->getOriginal()),
            };
}

function writeColorWithIf(SassColor $value): void
{
        $format = $value->getFormat();

            if ($format === ColorFormatEnum::rgbFunction) {
                writeRgb($value);
            } elseif ($format === ColorFormatEnum::hslFunction) {
                writeHsl($value);
            } else {
                write($format->getOriginal());
            }
}

function writeRgb(SassColor $color): void {
// Omitted
}
function writeHsl(SassColor $color): void {
// Omitted
}

function write(string $text): void {
// Omitted
}

In the code snippet above, as ColorFormat allows only ColorFormatEnum and SpanColorFormat and I'm checking explicitly all cases of the enum, I would expect the default branch of writeColorWithMatch and the else branch of writeColorWithIf to know that $format must be a SpanColorFormat there (and so calling getOriginal is OK.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions