-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathMermaidable.php
More file actions
80 lines (69 loc) 路 2.91 KB
/
Copy pathMermaidable.php
File metadata and controls
80 lines (69 loc) 路 2.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
<?php
namespace uuf6429\StateEngine\Implementation\Traits;
use uuf6429\StateEngine\Interfaces\DescribableInterface;
use uuf6429\StateEngine\Interfaces\StateInterface;
use uuf6429\StateEngine\Interfaces\TransitionInterface;
use uuf6429\StateEngine\Interfaces\TransitionRepositoryInterface;
/**
* This trait provides a method for generating a Mermaid State diagram of the various states and transitions. You'd
* typically `use` this in a class implementing {@see TransitionRepositoryInterface}.
*/
trait Mermaidable
{
/**
* @return iterable<TransitionInterface>
*/
abstract public function all(): iterable;
public function toMermaid(): string
{
/**
* @return array<string, array{id: string, text: string}>
*/
$extractStateInfo = static function (TransitionInterface ...$transitions): array {
$result = [];
foreach ($transitions as $transition) {
/** @var StateInterface $state */
foreach ([$transition->getOldState(), $transition->getNewState()] as $state) {
$stateName = $state->getName();
$result[$stateName] ??= [
'id' => sprintf('s%d_%s', count($result) + 1, preg_replace('/\W/', '_', $stateName)),
'text' => ($state instanceof DescribableInterface) ? $state->getDescription() : $stateName,
];
}
}
return $result;
};
/**
* @param array<string, array{id: string, text: string}> $stateInfo
* @return iterable<string>
*/
$generateNodesIds = static function (array $stateInfo): iterable {
foreach ($stateInfo as ['id' => $stateId, 'text' => $stateText]) {
yield " $stateId: $stateText";
}
};
/**
* @param array<string, array{id: string, text: string}> $stateInfo
* @return iterable<string>
*/
$generateNodesAndEdges = static function (array $stateInfo, TransitionInterface ...$transitions): iterable {
foreach ($transitions as $transition) {
$oldStateId = $stateInfo[$transition->getOldState()->getName()]['id'];
$newStateId = $stateInfo[$transition->getNewState()->getName()]['id'];
yield $transition instanceof DescribableInterface
? sprintf(' %s --> %s : %s', $oldStateId, $newStateId, $transition->getDescription())
: sprintf(' %s --> %s', $oldStateId, $newStateId);
}
};
$transitions = iterator_to_array($this->all());
$stateInfo = $extractStateInfo(...$transitions);
return implode(
PHP_EOL,
[
'stateDiagram',
...$generateNodesIds($stateInfo),
...$generateNodesAndEdges($stateInfo, ...$transitions),
],
);
}
}