Skip to content

Commit 83ff070

Browse files
committed
Add the Extension interface
1 parent dd08ae2 commit 83ff070

File tree

8 files changed

+103
-90
lines changed

8 files changed

+103
-90
lines changed

README.md

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -277,8 +277,8 @@ var_dump($ext->data === "\xaa"); // bool(true)
277277

278278
In addition to [the basic types](https://github.com/msgpack/msgpack/blob/master/spec.md#type-system),
279279
the library provides functionality to serialize and deserialize arbitrary types. In order to support a custom
280-
type you need to create and register a transformer. The transformer should implement either or both the `CanPack`
281-
and/or the `CanUnpackExt` interface.
280+
type you need to create and register a transformer. The transformer should implement either the `CanPack` interface
281+
or the `Extension` interface.
282282

283283
The purpose of `CanPack` transformers is to serialize a specific value to one of the basic MessagePack types. A good
284284
example of such a transformer is a `MapTransformer` that comes with the library. It serializes `Map` objects (which
@@ -324,26 +324,37 @@ $packed = $packer->pack([
324324
]);
325325
```
326326

327-
Transformers implementing the `CanUnpackExt` interface are intended for unpacking
328-
[extension types](https://github.com/msgpack/msgpack/blob/master/spec.md#extension-types).
329-
With the help of the abstract class [Extension](src/TypeTransformer/Extension.php) you can extend
330-
the MessagePack protocol with your own types. For example, the code below shows how to create
331-
an extension that allows you to work transparently with `DateTime` objects:
327+
Transformers implementing the `Extension` interface are intended to handle [extension types](https://github.com/msgpack/msgpack/blob/master/spec.md#extension-types).
328+
For example, the code below shows how to create an extension that allows you to work transparently with `DateTime` objects:
332329

333330
```php
334331
use MessagePack\BufferUnpacker;
335332
use MessagePack\Packer;
336333
use MessagePack\TypeTransformer\Extension;
337334

338-
class DateTimeExtension extends Extension
335+
class DateTimeExtension implements Extension
339336
{
340-
protected function packExt(Packer $packer, $value) : ?string
337+
private $type;
338+
339+
public function __construct(int $type)
340+
{
341+
$this->type = $type;
342+
}
343+
344+
public function getType() : int
345+
{
346+
return $this->type;
347+
}
348+
349+
public function pack(Packer $packer, $value) : ?string
341350
{
342351
if (!$value instanceof \DateTimeInterface) {
343352
return null;
344353
}
345354

346-
return $packer->packStr($value->format('Y-m-d\TH:i:s.uP'));
355+
return $packer->packExt($this->type,
356+
$packer->packStr($value->format('Y-m-d\TH:i:s.uP'))
357+
);
347358
}
348359

349360
public function unpackExt(BufferUnpacker $unpacker, int $extLength)

examples/MessagePack/ArrayIteratorExtension.php

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,21 @@
1515
use MessagePack\Packer;
1616
use MessagePack\TypeTransformer\Extension;
1717

18-
class ArrayIteratorExtension extends Extension
18+
class ArrayIteratorExtension implements Extension
1919
{
20-
protected function packExt(Packer $packer, $value) : ?string
20+
private $type;
21+
22+
public function __construct(int $type)
23+
{
24+
$this->type = $type;
25+
}
26+
27+
public function getType() : int
28+
{
29+
return $this->type;
30+
}
31+
32+
public function pack(Packer $packer, $value) : ?string
2133
{
2234
if (!$value instanceof \ArrayIterator) {
2335
return null;
@@ -30,7 +42,9 @@ protected function packExt(Packer $packer, $value) : ?string
3042
++$size;
3143
}
3244

33-
return $packer->packArrayHeader($size).$data;
45+
return $packer->packExt($this->type,
46+
$packer->packArrayHeader($size).$data
47+
);
3448
}
3549

3650
public function unpackExt(BufferUnpacker $unpacker, int $extLength)

examples/MessagePack/DateTimeExtension.php

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,29 @@
1515
use MessagePack\Packer;
1616
use MessagePack\TypeTransformer\Extension;
1717

18-
class DateTimeExtension extends Extension
18+
class DateTimeExtension implements Extension
1919
{
20-
protected function packExt(Packer $packer, $value) : ?string
20+
private $type;
21+
22+
public function __construct(int $type)
23+
{
24+
$this->type = $type;
25+
}
26+
27+
public function getType() : int
28+
{
29+
return $this->type;
30+
}
31+
32+
public function pack(Packer $packer, $value) : ?string
2133
{
2234
if (!$value instanceof \DateTimeInterface) {
2335
return null;
2436
}
2537

26-
return $packer->packStr($value->format('Y-m-d\TH:i:s.uP'));
38+
return $packer->packExt($this->type,
39+
$packer->packStr($value->format('Y-m-d\TH:i:s.uP'))
40+
);
2741
}
2842

2943
public function unpackExt(BufferUnpacker $unpacker, int $extLength)

examples/MessagePack/PackedMapExtension.php

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,21 @@
1515
use MessagePack\Packer;
1616
use MessagePack\TypeTransformer\Extension;
1717

18-
class PackedMapExtension extends Extension
18+
class PackedMapExtension implements Extension
1919
{
20-
protected function packExt(Packer $packer, $value) : ?string
20+
private $type;
21+
22+
public function __construct(int $type)
23+
{
24+
$this->type = $type;
25+
}
26+
27+
public function getType() : int
28+
{
29+
return $this->type;
30+
}
31+
32+
public function pack(Packer $packer, $value) : ?string
2133
{
2234
if (!$value instanceof PackedMap) {
2335
return null;
@@ -32,9 +44,11 @@ protected function packExt(Packer $packer, $value) : ?string
3244
++$size;
3345
}
3446

35-
return $packer->packMap($value->schema)
36-
.$packer->packArrayHeader($size)
37-
.$data;
47+
return $packer->packExt($this->type,
48+
$packer->packMap($value->schema).
49+
$packer->packArrayHeader($size).
50+
$data
51+
);
3852
}
3953

4054
public function unpackExt(BufferUnpacker $unpacker, int $extLength)

src/BufferUnpacker.php

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
use MessagePack\Exception\IntegerOverflowException;
1616
use MessagePack\Exception\InvalidOptionException;
1717
use MessagePack\Exception\UnpackingFailedException;
18-
use MessagePack\TypeTransformer\CanUnpackExt;
18+
use MessagePack\TypeTransformer\Extension;
1919

2020
class BufferUnpacker
2121
{
@@ -25,18 +25,18 @@ class BufferUnpacker
2525
private $isBigIntAsGmp;
2626

2727
/**
28-
* @var CanUnpackExt[]
28+
* @var Extension[]
2929
*/
30-
private $transformers = [];
30+
private $extensions = [];
3131

3232
/**
3333
* @param string $buffer
3434
* @param UnpackOptions|int|null $options
35-
* @param CanUnpackExt[] $transformers
35+
* @param Extension[] $extensions
3636
*
3737
* @throws InvalidOptionException
3838
*/
39-
public function __construct(string $buffer = '', $options = null, array $transformers = [])
39+
public function __construct(string $buffer = '', $options = null, array $extensions = [])
4040
{
4141
if (null === $options) {
4242
$options = UnpackOptions::fromDefaults();
@@ -49,22 +49,22 @@ public function __construct(string $buffer = '', $options = null, array $transfo
4949

5050
$this->buffer = $buffer;
5151

52-
if ([] !== $transformers) {
53-
$this->transformers = [];
54-
foreach ($transformers as $transformer) {
55-
$this->transformers[$transformer->getType()] = $transformer;
52+
if ([] !== $extensions) {
53+
$this->extensions = [];
54+
foreach ($extensions as $extension) {
55+
$this->extensions[$extension->getType()] = $extension;
5656
}
5757
}
5858
}
5959

60-
public function extendWith(CanUnpackExt $transformer, CanUnpackExt ...$transformers) : self
60+
public function extendWith(Extension $extension, Extension ...$extensions) : self
6161
{
6262
$new = clone $this;
63-
$new->transformers[$transformer->getType()] = $transformer;
63+
$new->extensions[$extension->getType()] = $extension;
6464

65-
if ([] !== $transformers) {
66-
foreach ($transformers as $extraTransformer) {
67-
$new->transformers[$extraTransformer->getType()] = $extraTransformer;
65+
if ([] !== $extensions) {
66+
foreach ($extensions as $extraExtension) {
67+
$new->extensions[$extraExtension->getType()] = $extraExtension;
6868
}
6969
}
7070

@@ -652,8 +652,8 @@ private function unpackExtData($length)
652652
$type -= 0x100;
653653
}
654654

655-
if (isset($this->transformers[$type])) {
656-
return $this->transformers[$type]->unpackExt($this, $length);
655+
if (isset($this->extensions[$type])) {
656+
return $this->extensions[$type]->unpackExt($this, $length);
657657
}
658658

659659
$data = \substr($this->buffer, $this->offset, $length);

src/TypeTransformer/CanUnpackExt.php

Lines changed: 0 additions & 21 deletions
This file was deleted.

src/TypeTransformer/Extension.php

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,30 +11,11 @@
1111

1212
namespace MessagePack\TypeTransformer;
1313

14-
use MessagePack\Packer;
14+
use MessagePack\BufferUnpacker;
1515

16-
abstract class Extension implements CanPack, CanUnpackExt
16+
interface Extension extends CanPack
1717
{
18-
private $type;
18+
public function getType() : int;
1919

20-
public function __construct(int $type)
21-
{
22-
$this->type = $type;
23-
}
24-
25-
public function getType() : int
26-
{
27-
return $this->type;
28-
}
29-
30-
public function pack(Packer $packer, $value) : ?string
31-
{
32-
if (null === $data = $this->packExt($packer, $value)) {
33-
return null;
34-
}
35-
36-
return $packer->packExt($this->type, $data);
37-
}
38-
39-
abstract protected function packExt(Packer $packer, $value) : ?string;
20+
public function unpackExt(BufferUnpacker $unpacker, int $extLength);
4021
}

tests/Unit/BufferUnpackerTest.php

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
use MessagePack\Exception\InvalidOptionException;
1818
use MessagePack\Exception\UnpackingFailedException;
1919
use MessagePack\Ext;
20-
use MessagePack\TypeTransformer\CanUnpackExt;
20+
use MessagePack\TypeTransformer\Extension;
2121
use MessagePack\UnpackOptions;
2222
use PHPUnit\Framework\Error\Warning;
2323
use PHPUnit\Framework\TestCase;
@@ -301,7 +301,7 @@ public function testConstructorSetsTransformers() : void
301301
$obj = new \stdClass();
302302
$type = 5;
303303

304-
$transformer = $this->createMock(CanUnpackExt::class);
304+
$transformer = $this->createMock(Extension::class);
305305
$transformer->method('getType')->willReturn($type);
306306
$transformer->expects(self::once())->method('unpackExt')
307307
->with($this->isInstanceOf(BufferUnpacker::class), 1)
@@ -320,19 +320,19 @@ public function testUnpackCustomType() : void
320320
$type1 = 5;
321321
$type2 = 6;
322322

323-
$transformer1 = $this->createMock(CanUnpackExt::class);
324-
$transformer1->method('getType')->willReturn($type1);
325-
$transformer1->expects(self::once())->method('unpackExt')
323+
$extension1 = $this->createMock(Extension::class);
324+
$extension1->method('getType')->willReturn($type1);
325+
$extension1->expects(self::once())->method('unpackExt')
326326
->with($this->isInstanceOf(BufferUnpacker::class), 1)
327327
->willReturn($obj1);
328328

329-
$transformer2 = $this->createMock(CanUnpackExt::class);
330-
$transformer2->method('getType')->willReturn($type2);
331-
$transformer2->expects(self::once())->method('unpackExt')
329+
$extension2 = $this->createMock(Extension::class);
330+
$extension2->method('getType')->willReturn($type2);
331+
$extension2->expects(self::once())->method('unpackExt')
332332
->with($this->isInstanceOf(BufferUnpacker::class), 1)
333333
->willReturn($obj2);
334334

335-
$unpacker = $this->unpacker->extendWith($transformer1, $transformer2);
335+
$unpacker = $this->unpacker->extendWith($extension1, $extension2);
336336

337337
self::assertSame($obj1, $unpacker->reset("\xd4\x05\x01")->unpack());
338338
self::assertSame($obj2, $unpacker->reset("\xd4\x06\x01")->unpack());

0 commit comments

Comments
 (0)