Skip to content

Commit 2568629

Browse files
committed
used transition states
1 parent b19b970 commit 2568629

File tree

2 files changed

+145
-20
lines changed

2 files changed

+145
-20
lines changed

src/Bolt/ServerStateRepository.php

Lines changed: 81 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,17 @@
1313

1414
namespace Laudis\Neo4j\Bolt;
1515

16+
use function array_filter;
17+
use function array_map;
1618
use function in_array;
1719

1820
/**
1921
* @see https://7687.org/bolt/bolt-protocol-server-state-specification-4.html#version-43
22+
*
23+
* @psalm-immutable
2024
*/
2125
final class ServerStateRepository
2226
{
23-
private const KEYS = ['State' => 0, 'Request Message' => 1, 'Triggers Signal' => 2, 'Server Response' => 3, 'New State' => 4];
24-
public function canSendMessage(string $state, string $message): bool
25-
{
26-
return in_array($message, $this->getMessagesForState($state), true);
27-
}
28-
29-
public function isValidState(string $state): bool
30-
{
31-
return in_array($state, $this->getStates(), true);
32-
}
33-
3427
private const TRANSITIONS = [
3528
['CONNECTED', 'HELLO', null, 'SUCCESS', 'READY'],
3629
['CONNECTED', 'HELLO', null, 'FAILURE', 'DEFUNCT'],
@@ -89,27 +82,95 @@ public function isValidState(string $state): bool
8982
['INTERRUPTED', 'GOODBYE', 'DISCONNECT', null, 'DEFUNCT'],
9083
];
9184

85+
/** @var list<StateTransition> */
86+
private array $transitions;
87+
88+
public function __construct()
89+
{
90+
$this->transitions = array_map(static fn ($x) => StateTransition::fromArray($x), self::TRANSITIONS);
91+
}
92+
9293
/**
93-
* @return list<string>
94+
* @return array<string, string|null>
9495
*/
95-
public function getMessagesForState(string $state): array
96+
public function expectedStates(string $state, string $message): array
97+
{
98+
$tbr = [];
99+
foreach ($this->getAvailableTransitionsForState($state) as $transition) {
100+
$tbr[$transition->getServerResponse() ?? ''] = $transition->getNewState();
101+
}
102+
103+
return $tbr;
104+
}
105+
106+
/**
107+
* Returns the expected state for the response.
108+
*/
109+
public function expectedStateForResponse(string $state, string $message, string $response): ?string
110+
{
111+
return $this->expectedStates($state, $message)[$response] ?? null;
112+
}
113+
114+
/**
115+
* Returns the signal if the state transition response triggers one, null otherwise.
116+
*/
117+
public function expectedSignalForResponse(string $state, string $message, string $response): ?string
96118
{
97-
$messages = [];
98-
foreach (self::TRANSITIONS as $transition) {
99-
if ($transition[self::KEYS['State']] === $state) {
100-
$messages[] = $transition[self::KEYS['Request Message']];
119+
foreach ($this->getAvailableTransitionsForStateAndMessage($state, $message) as $transition) {
120+
if ($transition->getTriggersSignal()) {
121+
return $transition->getTriggersSignal();
101122
}
102123
}
103124

104-
return $messages;
125+
return null;
126+
}
127+
128+
/**
129+
* @return list<StateTransition>
130+
*/
131+
public function getAvailableTransitionsForStateAndMessage(string $state, string $message): array
132+
{
133+
return array_values(array_filter(
134+
$this->getAvailableTransitionsForState($state),
135+
static fn ($x) => $x->getMessage() === $message
136+
));
137+
}
138+
139+
/**
140+
* Returns the available transitions for the state.
141+
*
142+
* @return list<StateTransition>
143+
*/
144+
private function getAvailableTransitionsForState(string $state): array
145+
{
146+
return array_values(
147+
array_filter($this->transitions, static fn ($x) => $x->getOriginalState() === $state)
148+
);
149+
}
150+
151+
public function canSendMessage(string $state, string $message): bool
152+
{
153+
return in_array($message, $this->getMessagesForState($state), true);
154+
}
155+
156+
public function isValidState(string $state): bool
157+
{
158+
return in_array($state, $this->getStates(), true);
159+
}
160+
161+
/**
162+
* @return list<string>
163+
*/
164+
public function getMessagesForState(string $state): array
165+
{
166+
return array_map(static fn ($x) => $x->getMessage(), $this->getAvailableTransitionsForState($state));
105167
}
106168

107169
/**
108170
* @return list<string>
109171
*/
110172
public function getStates(): array
111173
{
112-
/** @var list<string> */
113-
return array_unique(array_map(static fn (array $x) => $x[self::KEYS['State']], self::TRANSITIONS));
174+
return array_values(array_unique(array_map(static fn ($x) => $x->getOriginalState(), $this->transitions)));
114175
}
115176
}

src/Bolt/StateTransition.php

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the Laudis Neo4j package.
7+
*
8+
* (c) Laudis technologies <http://laudis.tech>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Laudis\Neo4j\Bolt;
15+
16+
/**
17+
* @psalm-immutable
18+
*/
19+
final class StateTransition
20+
{
21+
public function __construct(
22+
private string $originalState,
23+
private string $message,
24+
private ?string $triggersSignal,
25+
private ?string $serverResponse,
26+
private ?string $newState
27+
) {
28+
}
29+
30+
public function getOriginalState(): string
31+
{
32+
return $this->originalState;
33+
}
34+
35+
public function getMessage(): string
36+
{
37+
return $this->message;
38+
}
39+
40+
public function getTriggersSignal(): ?string
41+
{
42+
return $this->triggersSignal;
43+
}
44+
45+
public function getServerResponse(): ?string
46+
{
47+
return $this->serverResponse;
48+
}
49+
50+
public function getNewState(): ?string
51+
{
52+
return $this->newState;
53+
}
54+
55+
/**
56+
* @param array{0: string, 1: string, 2: string|null, 3: string|null, 4: string|null} $params
57+
*
58+
* @pure
59+
*/
60+
public static function fromArray(array $params): self
61+
{
62+
return new self($params[0], $params[1], $params[2], $params[3], $params[4]);
63+
}
64+
}

0 commit comments

Comments
 (0)