Skip to content

Commit 306982e

Browse files
authored
Merge pull request #3 from petrknap/serializer
Implemented `Serializer`
2 parents 9634cb6 + 5abda62 commit 306982e

11 files changed

+331
-3
lines changed

README.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Library for work with binaries
22

33
Library for basic work with binary data in PHP.
4-
See the sample below for more information, or check out [`CoderInterface`](./src/CoderInterface.php).
4+
See the examples below for more information, or check out [`CoderInterface`](./src/CoderInterface.php) and [`SerializerInterface`](./src/SerializerInterface.php).
55

66
```php
77
use PetrKnap\Binary\Binary;
@@ -13,6 +13,19 @@ $decoded = Binary::decode($encoded)->base64()->zlib()->checksum()->getData();
1313
printf('Data was coded into `%s` %s.', $encoded, $decoded === $data ? 'successfully' : 'unsuccessfully');
1414
```
1515

16+
```php
17+
use PetrKnap\Binary\Binary;
18+
19+
$data = [
20+
'type' => 'image/png',
21+
'data' => base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAA1JREFUGFdj+L+U4T8ABu8CpCYJ1DQAAAAASUVORK5CYII='),
22+
];
23+
$serialized = Binary::serialize($data);
24+
$unserialized = Binary::unserialize($serialized);
25+
26+
printf('Data was serialized into `%s` %s.', base64_encode($serialized), $unserialized === $data ? 'successfully' : 'unsuccessfully');
27+
```
28+
1629
---
1730

1831
Run `composer require petrknap/binary` to install it.

src/Binary.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,23 @@ public static function decode(string $data): Decoder
1515
{
1616
return new Decoder($data);
1717
}
18+
19+
public static function serialize(mixed $data): string
20+
{
21+
return self::getSerializer()->serialize(serializable: $data);
22+
}
23+
24+
public static function unserialize(string $data): mixed
25+
{
26+
return self::getSerializer()->unserialize(serialized: $data);
27+
}
28+
29+
private static function getSerializer(): Serializer
30+
{
31+
static $serializer;
32+
return $serializer ??= new Serializer(
33+
new Encoder(),
34+
new Decoder(),
35+
);
36+
}
1837
}

src/Coder.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,15 @@ abstract class Coder implements CoderInterface
1717
];
1818

1919
public function __construct(
20-
protected readonly string $data,
20+
protected readonly string $data = '',
2121
) {
2222
}
2323

24+
public function withData(string $data): static
25+
{
26+
return static::create($this, $data);
27+
}
28+
2429
public function getData(): string
2530
{
2631
return $this->data;

src/CoderInterface.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ interface CoderInterface
1111
{
1212
public const CHECKSUM_ALGORITHM = 'crc32';
1313

14+
public function withData(string $data): static;
15+
1416
public function getData(): string;
1517

1618
/**
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PetrKnap\Binary\Exception;
6+
7+
use PetrKnap\Binary\SerializerInterface;
8+
use RuntimeException;
9+
use Throwable;
10+
11+
final class CouldNotSerializeData extends RuntimeException implements SerializerException
12+
{
13+
public function __construct(
14+
private readonly SerializerInterface $serializer,
15+
private readonly mixed $data,
16+
?Throwable $reason = null,
17+
) {
18+
parent::__construct(
19+
sprintf(
20+
'%s could not serialize %s',
21+
$serializer::class,
22+
is_object($data) ? $data::class : gettype($data),
23+
),
24+
previous: $reason,
25+
);
26+
}
27+
28+
public function getSerializer(): SerializerInterface
29+
{
30+
return $this->serializer;
31+
}
32+
33+
public function getData(): mixed
34+
{
35+
return $this->data;
36+
}
37+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PetrKnap\Binary\Exception;
6+
7+
use PetrKnap\Binary\SerializerInterface;
8+
use RuntimeException;
9+
use Throwable;
10+
11+
final class CouldNotUnserializeData extends RuntimeException implements SerializerException
12+
{
13+
public function __construct(
14+
private readonly SerializerInterface $serializer,
15+
private readonly string $data,
16+
?Throwable $reason = null,
17+
) {
18+
parent::__construct(
19+
sprintf(
20+
'%s could not unserialize string(%d)',
21+
$serializer::class,
22+
strlen($data)
23+
),
24+
previous: $reason,
25+
);
26+
}
27+
28+
public function getSerializer(): SerializerInterface
29+
{
30+
return $this->serializer;
31+
}
32+
33+
public function getData(): string
34+
{
35+
return $this->data;
36+
}
37+
}

src/Exception/SerializerException.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PetrKnap\Binary\Exception;
6+
7+
use PetrKnap\Binary\SerializerInterface;
8+
9+
interface SerializerException extends BinaryException
10+
{
11+
public function getSerializer(): SerializerInterface;
12+
}

src/Serializer.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PetrKnap\Binary;
6+
7+
use Throwable;
8+
9+
class Serializer implements SerializerInterface
10+
{
11+
public function __construct(
12+
protected readonly EncoderInterface $encoder,
13+
protected readonly DecoderInterface $decoder,
14+
) {
15+
}
16+
17+
public function serialize(mixed $serializable): string
18+
{
19+
try {
20+
$serialized = $this->doSerialize($serializable);
21+
return $this->encoder->withData($serialized)->zlib()->getData();
22+
} catch (Throwable $reason) {
23+
throw new Exception\CouldNotSerializeData($this, $serializable, $reason);
24+
}
25+
}
26+
27+
public function unserialize(string $serialized): mixed
28+
{
29+
try {
30+
$serialized = $this->decoder->withData($serialized)->zlib()->getData();
31+
return $this->doUnserialize($serialized);
32+
} catch (Throwable $reason) {
33+
throw new Exception\CouldNotUnserializeData($this, $serialized, $reason);
34+
}
35+
}
36+
37+
/**
38+
* Alternative to {@see serialize()}
39+
*
40+
* @throws Throwable
41+
*/
42+
protected function doSerialize(mixed $serializable): string
43+
{
44+
return serialize($serializable);
45+
}
46+
47+
/**
48+
* Alternative to {@see unserialize()}
49+
*
50+
* @throws Throwable
51+
*/
52+
protected function doUnserialize(string $serialized): mixed
53+
{
54+
return unserialize($serialized);
55+
}
56+
}

src/SerializerInterface.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PetrKnap\Binary;
6+
7+
interface SerializerInterface
8+
{
9+
/**
10+
* {@see serialize()} the serializable
11+
*
12+
* @throws Exception\CouldNotSerializeData
13+
*/
14+
public function serialize(mixed $serializable): string;
15+
16+
/**
17+
* {@see unserialize()} the serialized
18+
*
19+
* @throws Exception\CouldNotUnserializeData
20+
*/
21+
public function unserialize(string $serialized): mixed;
22+
}

tests/ReadmeTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ public static function getPathToMarkdownFile(): string
1818
public static function getExpectedOutputsOfPhpExamples(): iterable
1919
{
2020
return [
21-
'coders' => 'Data was coded into `a8vMFCssyD2Rs5BB0Evt6tJv10J_b2Aoui0tcXT69aaPP9oIyB-fLeAHAA` successfully.',
21+
'coder' => 'Data was coded into `a8vMFCssyD2Rs5BB0Evt6tJv10J_b2Aoui0tcXT69aaPP9oIyB-fLeAHAA` successfully.',
22+
'serializer' => 'Data was serialized into `S7QysqoutjKxUiqpLEhVsi62srRSysxNTE/VL8hLB/GBUimJJYkgpoWxlVJngJ87L5cUFwMDA6+nh0sQkGYEYQ42ICkveqQTxCkOcndiWHdO5iVYlYtjiER48o/9Ux7aM7C9Z1qixnnFBCjB4Onq57LOKaFJyboWAA==` successfully.',
2223
];
2324
}
2425
}

0 commit comments

Comments
 (0)