Skip to content

Commit 0af64d6

Browse files
xepozzgithub-actions
andauthored
feat: RawValue implementation (#683)
* feat: support raw value * feat: simplify checks * feat: move test from harness to extra namespace * refactor: cleanup test * fix: correct tests * style(php-cs-fixer): fix coding standards * feat: rewrite solution with hard-coded raw value check * style(php-cs-fixer): fix coding standards * feat: add types --------- Co-authored-by: github-actions <github-actions@users.noreply.github.com>
1 parent 1247f77 commit 0af64d6

7 files changed

Lines changed: 176 additions & 35 deletions

File tree

src/DataConverter/DataConverter.php

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,27 +39,33 @@ public static function createDefault(): DataConverterInterface
3939
);
4040
}
4141

42-
public function fromPayload(Payload $payload, $type)
42+
/**
43+
* @param string|\ReflectionClass|\ReflectionType|Type|null $type
44+
*/
45+
public function fromPayload(Payload $payload, $type): mixed
4346
{
47+
$type = Type::create($type);
48+
49+
if ($type->isClass() && $type->getName() === RawValue::class) {
50+
return new RawValue($payload);
51+
}
52+
4453
/** @var \ArrayAccess $meta */
4554
$meta = $payload->getMetadata();
4655

4756
$encoding = $meta[EncodingKeys::METADATA_ENCODING_KEY];
4857

4958
if (!isset($this->converters[$encoding])) {
50-
throw new DataConverterException(\sprintf('Undefined payload encoding %s', $encoding));
59+
throw new DataConverterException(\sprintf('Undefined payload encoding "%s"', $encoding));
5160
}
5261

53-
$type = Type::create($type);
54-
if (\in_array($type->getName(), [Type::TYPE_VOID, Type::TYPE_NULL, Type::TYPE_FALSE, Type::TYPE_TRUE], true)) {
55-
return match ($type->getName()) {
56-
Type::TYPE_VOID, Type::TYPE_NULL => null,
57-
Type::TYPE_TRUE => true,
58-
Type::TYPE_FALSE => false,
59-
};
60-
}
61-
62-
return $this->converters[$encoding]->fromPayload($payload, $type);
62+
return match ($type->getName()) {
63+
Type::TYPE_VOID,
64+
Type::TYPE_NULL => null,
65+
Type::TYPE_TRUE => true,
66+
Type::TYPE_FALSE => false,
67+
default => $this->converters[$encoding]->fromPayload($payload, $type),
68+
};
6369
}
6470

6571
/**
@@ -69,6 +75,9 @@ public function fromPayload(Payload $payload, $type)
6975
*/
7076
public function toPayload($value): Payload
7177
{
78+
if ($value instanceof RawValue) {
79+
return $value->getPayload();
80+
}
7281
foreach ($this->converters as $converter) {
7382
$payload = $converter->toPayload($value);
7483

src/DataConverter/DataConverterInterface.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,10 @@ interface DataConverterInterface
2323
* @psalm-mutation-free
2424
* @throws DataConverterException
2525
*/
26-
public function fromPayload(Payload $payload, $type);
26+
public function fromPayload(Payload $payload, mixed $type);
2727

2828
/**
29-
* @param mixed $value
30-
*
3129
* @throws DataConverterException
3230
*/
33-
public function toPayload($value): Payload;
31+
public function toPayload(mixed $value): Payload;
3432
}

src/DataConverter/EncodingKeys.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ final class EncodingKeys
1717
public const METADATA_MESSAGE_TYPE = 'messageType';
1818
public const METADATA_ENCODING_NULL = 'binary/null';
1919
public const METADATA_ENCODING_RAW = 'binary/plain';
20+
public const METADATA_ENCODING_RAW_VALUE = 'binary';
2021
public const METADATA_ENCODING_JSON = 'json/plain';
2122
public const METADATA_ENCODING_PROTOBUF_JSON = 'json/protobuf';
2223
public const METADATA_ENCODING_PROTOBUF = 'binary/protobuf';

src/DataConverter/RawValue.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
/**
4+
* This file is part of Temporal package.
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
declare(strict_types=1);
11+
12+
namespace Temporal\DataConverter;
13+
14+
use Temporal\Api\Common\V1\Payload;
15+
16+
final class RawValue
17+
{
18+
private Payload $payload;
19+
20+
public function __construct(Payload $data)
21+
{
22+
$this->payload = $data;
23+
}
24+
25+
public function getPayload(): Payload
26+
{
27+
return $this->payload;
28+
}
29+
}

src/DataConverter/Type.php

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -79,25 +79,14 @@ public static function fromReflectionType(\ReflectionType $type): self
7979
*/
8080
public static function create($type): Type
8181
{
82-
switch (true) {
83-
case $type instanceof ReturnType:
84-
return new self($type->name, $type->nullable);
85-
86-
case $type instanceof self:
87-
return $type;
88-
89-
case \is_string($type):
90-
return new self($type);
91-
92-
case $type instanceof \ReflectionClass:
93-
return self::fromReflectionClass($type);
94-
95-
case $type instanceof \ReflectionType:
96-
return self::fromReflectionType($type);
97-
98-
default:
99-
return new self();
100-
}
82+
return match (true) {
83+
$type instanceof ReturnType => new self($type->name, $type->nullable),
84+
$type instanceof self => $type,
85+
\is_string($type) => new self($type),
86+
$type instanceof \ReflectionClass => self::fromReflectionClass($type),
87+
$type instanceof \ReflectionType => self::fromReflectionType($type),
88+
default => new self(),
89+
};
10190
}
10291

10392
public function getName(): string
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Temporal\Tests\Acceptance\Extra\DataConverter\RawValue;
6+
7+
use PHPUnit\Framework\Attributes\Test;
8+
use Temporal\Activity\ActivityInterface;
9+
use Temporal\Activity\ActivityMethod;
10+
use Temporal\Activity\ActivityOptions;
11+
use Temporal\Api\Common\V1\Payload;
12+
use Temporal\Client\WorkflowStubInterface;
13+
use Temporal\DataConverter\RawValue;
14+
use Temporal\Tests\Acceptance\App\Attribute\Stub;
15+
use Temporal\Tests\Acceptance\App\TestCase;
16+
use Temporal\Workflow;
17+
use Temporal\Workflow\WorkflowInterface;
18+
use Temporal\Workflow\WorkflowMethod;
19+
20+
class RawValueTest extends TestCase
21+
{
22+
#[Test]
23+
public function check(
24+
#[Stub('Extra_DataConverter_RawValue')]
25+
WorkflowStubInterface $stub,
26+
): void {
27+
$result = $stub->getResult(RawValue::class);
28+
29+
self::assertInstanceOf(RawValue::class, $result);
30+
self::assertInstanceOf(Payload::class, $result->getPayload());
31+
self::assertSame('hello world', $result->getPayload()->getData());
32+
}
33+
}
34+
35+
#[WorkflowInterface]
36+
class FeatureWorkflow
37+
{
38+
#[WorkflowMethod('Extra_DataConverter_RawValue')]
39+
public function run()
40+
{
41+
$rawValue = new RawValue(new Payload(['data' => 'hello world']));
42+
43+
$activity = Workflow::newActivityStub(
44+
RawValueActivity::class,
45+
ActivityOptions::new()
46+
->withScheduleToCloseTimeout('1 minute'),
47+
);
48+
49+
return yield $activity->bypass($rawValue);
50+
}
51+
}
52+
53+
#[ActivityInterface(prefix: 'RawValueActivity.')]
54+
class RawValueActivity
55+
{
56+
#[ActivityMethod]
57+
public function bypass(RawValue $arg): RawValue
58+
{
59+
return $arg;
60+
}
61+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
/**
4+
* This file is part of Temporal package.
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
declare(strict_types=1);
11+
12+
namespace Unit\DataConverter;
13+
14+
use Temporal\Api\Common\V1\Payload;
15+
use Temporal\DataConverter\DataConverter;
16+
use Temporal\DataConverter\DataConverterInterface;
17+
use Temporal\DataConverter\EncodingKeys;
18+
use Temporal\DataConverter\RawValue;
19+
use Temporal\Tests\Unit\AbstractUnit;
20+
21+
/**
22+
* @group unit
23+
* @group data-converter
24+
*/
25+
class RawValueConverterTest extends AbstractUnit
26+
{
27+
public function testRawPayloadEncoding(): void
28+
{
29+
$innerPayload = new Payload(['data' => 1]);
30+
$message = new RawValue($innerPayload);
31+
32+
$payload = DataConverter::createDefault()->toPayload($message);
33+
34+
self::assertSame($innerPayload, $payload);
35+
self::assertSame(EncodingKeys::METADATA_ENCODING_RAW_VALUE, $payload->getMetadata()[EncodingKeys::METADATA_ENCODING_KEY]);
36+
}
37+
38+
public function testRawPayloadDecoding(): void
39+
{
40+
$innerPayload = new Payload(['data' => 1]);
41+
$message = new RawValue($innerPayload);
42+
43+
$encoded = DataConverter::createDefault()->toPayload($message);
44+
$decoded = DataConverter::createDefault()->fromPayload($encoded, RawValue::class);
45+
46+
self::assertInstanceOf(RawValue::class, $decoded);
47+
self::assertSame($decoded->getPayload(), $encoded);
48+
}
49+
50+
protected function create(): DataConverterInterface
51+
{
52+
return DataConverter::createDefault();
53+
}
54+
}

0 commit comments

Comments
 (0)