Skip to content

Latest commit

 

History

History
178 lines (134 loc) · 4.86 KB

state.md

File metadata and controls

178 lines (134 loc) · 4.86 KB

State

State is a feature that allows you to use enums state-driven. Think of state pattern. Out of the box it operates like a one-way traffic-light, from top to bottom. But you can make it as complex as you need it to be.

Usage

use Henzeb\Enumhancer\Concerns\State;

enum elevator
{
    use State;

    case Open;
    case Close;
    case Move;
    case Stop;
}

examples

Basic usage

elevator::Open->allowsTransition('Close'); // returns true
elevator::Open->allowsTransition(elevator::Move); // returns false

elevator::Open->transitionTo('Close'); // returns elevator::Close
elevator::Move->transitionTo(elevator::Close); // throws exception
elevator::Close->transitionTo('Open'); // throws IllegalEnumTransitionException

elevator::Open->to(elevator::Move) // throws IllegalEnumTransitionException
elevator::Open->tryTo(elevator::Move) // returns elevator::Open
elevator::Open->tryTo(elevator::Close) // returns elevator::Close

/** using magic */
elevator::Open->toMove() // throws IllegalEnumTransitionException
elevator::Open->tryToMove() // returns elevator::Open
elevator::Open->tryToClose() // returns elevator::Close

Complex Usage

use Henzeb\Enumhancer\Concerns\State;

enum elevator
{
    use State;

    case Open;
    case Close;
    case Move;
    case Stop;

    public static function customTransitions(): array
    {
        return [
            'open' => 'close',
            'close' => [
                'open',
                'move'
            ],
            'move' => 'stop',
            'stop' => 'open'
        ];
    }
}

elevator::Open->transitionTo(elevator::Close)
    ->transitionTo(elevator::Open)
    ->transitionTo(elevator::Close)
    ->transitionTo('Move')
    ->transitionTo(elevator::Stop)
    ->transitionTo('Open')
    ->transitionTo('Close'); //eventually returns elevator::Close

elevator::Move->transitionTo('Open'); //throws IllegalEnumTransitionException

The array returned by the customTransitions method can return an array containing the name or value as key, and the name, value or enum instance as value.

Note: You can only go one level deep.

Allowed transitions

When you want to present the transition options to your user, you can use allowedTransitions to get them (complex example):

elevator::Open->allowedTransitions(); // returns [elevator::Close]
elevator::Close->allowedTransitions(); // returns [elevator::Open, elevator::Move]
elevator::Move->allowedTransitions(); // returns [elevator::Stop]
elevator::Stop->allowedTransitions(); // returns [elevator::Open]

Note: when there are no transitions possible, allowedTranslations returns an empty array

Transition hooks

Transition hooks will give you more granular control about transitions. It allows you to allow a transaction based on a condition and it also allows you to do some other things when a transaction occurs.

For example: You could use it to allow stopping the elevator only when the floor is reached and you can change the current level by every move up or down.

We start out with making an TransitionHook class. The method-names are based on the enum's name. cases don't really matter here, just like always.

  • allows<From name><To name>
  • <From name><To name>

Example:

use Henzeb\Enumhancer\Contracts\TransitionHook;

class ElevatorHooks extends TransitionHook {
    private int $floor = 1;
    protected function allowsMoveStop(): bool
    {
        return false;
    }

    protected function closeMove() {
        $this->floor++;
    }
}
$hooks = new ElevatorHooks();
elevator::Move->allowTransition('stop', $hook); // returns false
elevator::Move->allowedTransitions($hook); // returns []
elevator::Move->transitionTo('stop', $hook); // throws IllegalEnumTransitionException
elevator::Close->allowTransition('move', $hook); // returns true
elevator::Close->transitionTo('move', $hook); // returns increases $floor to 2

elevator::Move->tryTo('stop', $hook); // returns elevator::Move
elevator::Move->to('stop', $hook); // throws IllegalEnumTransitionException
elevator::Close->tryTo('move', $hook); // returns elevator::Close
elevator::Close->to('move', $hook); // returns increases $floor to 2

/** using magic calls */
elevator::Move->tryToStop($hook); // returns elevator::Move
elevator::Move->toStop($hook); // throws IllegalEnumTransitionException
elevator::Close->tryToMove($hook); // returns elevator::Close
elevator::Close->toMove($hook); // returns increases $floor to 2

You can also add a TransitionHook directly on to your enum object.

enum elevator {
    use State;

    public static function transitionHooks(): ?TransitionHooks
    {
        return new ElevatorHooks();
    }
}

If you use both ways, both need to return true, in order to allow a transition.

Validation (Laravel)

see State

Casting (Laravel)

see Casting