Lines 100.00% 36 / 36
Methods 100.00% 3 / 3
Classes 100.00% 1 / 1
Name Lines Methods CRAP
 serialize 100.00% 12 / 12 100.00% 1 / 1 2
 unserialize 100.00% 23 / 23 100.00% 1 / 1 15
 describe 100.00% 1 / 1 100.00% 1 / 1 1
14final class MessageSerializer implements SerializerInterface
15{
16    #[\Override]
17    public function serialize(MessageInterface $message): string
18    {
19        try {
20            return json_encode([
21                'message' => [
22                    'id' => $message->getId(),
23                    'type' => $message->getType(),
24                    'created' => $message->getCreated(),
25                    'payload' => $message->getPayload(),
26                    'execute_at' => $message->getExecuteAt(),
27                    'retries' => $message->getRetries(),
28                ],
29            ], JSON_INVALID_UTF8_IGNORE | JSON_THROW_ON_ERROR);
30        } catch (JsonException $e) {
31            throw new SerializeException("Cannot serialize message {$message->getId()}: {$e->getMessage()}", $e->getCode(), previous: $e);
32        }
33    }
34
35    #[\Override]
36    public function unserialize(string $string): MessageInterface
37    {
38        try {
39            $data = json_decode($string, true, flags: JSON_THROW_ON_ERROR);
40        } catch (JsonException $e) {
41            throw new SerializeException('Cannot unserialize message: invalid JSON (' . $e->getMessage() . ') ' . $this->describe($string), $e->getCode(), previous: $e);
42        }
43        if (!is_array($data) || !isset($data['message'])) {
44            throw new SerializeException('Cannot unserialize message: no "message" key ' . $this->describe($string));
45        }
46        $message = $data['message'];
47        if (!is_array($message) || !isset($message['type'], $message['id'], $message['created'])) {
48            throw new SerializeException('Invalid message format: "message" needs type, id and created ' . $this->describe($string));
49        }
50
51        $type = $message['type'];
52        $id = $message['id'];
53        $created = $message['created'];
54        if (!is_string($type) || !is_string($id) || !is_numeric($created)) {
55            throw new SerializeException('Invalid message format: type and id must be strings and created a number ' . $this->describe($string));
56        }
57
58        $executeAt = null;
59        if (isset($message['execute_at']) && is_numeric($message['execute_at'])) {
60            $executeAt = (float) $message['execute_at'];
61        }
62
63        $retries = 0;
64        if (isset($message['retries']) && is_numeric($message['retries'])) {
65            $retries = (int) $message['retries'];
66        }
67
68        $payload = null;
69        if (isset($message['payload']) && is_array($message['payload'])) {
70            $payload = $message['payload'];
71        }
72
73        return new Message($type, $payload, $id, (float) $created, $executeAt, $retries);
74    }
75
76    private function describe(string $string): string
77    {
78        return '(' . strlen($string) . ' bytes, sha256 ' . substr(hash('sha256', $string), 0, 16) . ')';
79    }
80}