Skip to content

Commit e79fcb1

Browse files
committed
Supported BcMath\Number numberType
1 parent 1264d28 commit e79fcb1

17 files changed

Lines changed: 301 additions & 19 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ Key Features
6868
* implements standard interfaces: `IteratorAggregate`, `JsonSerializable`, and `Countable`
6969
* supports embedded, collections Transfer Objects
7070
* supports PHP primitive data types
71-
* supports `BackedEnum`, `DateTime`, `DateTimeImmutable`
71+
* supports `BackedEnum`, `DateTime`, `DateTimeImmutable`, and `BcMath\\Number`
7272
* supports asymmetric property visibility
7373
* integrates external Transfer Objects
7474

config/definition/transfer-generator.transfer.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ DefinitionProperty:
6060
type: DefinitionEmbeddedType
6161
dateTimeType:
6262
type: DefinitionEmbeddedType
63+
numberType:
64+
type: DefinitionEmbeddedType
6365
isNullable:
6466
type: bool
6567
required:

schema/definition.schema.json

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
},
4040
"dateTimeType": {
4141
"type": "string",
42-
"description": "Includes DateTimeImmutable or DateTime or any of theirs sub-classes with fully qualified Enum name with namespace, optionally with alias.",
42+
"description": "Includes DateTimeImmutable or DateTime or any of full sub-class path, optionally with alias.",
4343
"anyOf": [
4444
"DateTimeImmutable",
4545
"DateTime",
@@ -48,6 +48,13 @@
4848
}
4949
]
5050
},
51+
"numberType": {
52+
"type": "string",
53+
"description": "Includes BcMath\\Number.",
54+
"anyOf": [
55+
"BcMath\\Number"
56+
]
57+
},
5158
"required": {
5259
"type": "null",
5360
"description": "Marks the property as not nullable."
@@ -66,6 +73,8 @@
6673
"required": ["enumType"]
6774
}, {
6875
"required": ["dateTimeType"]
76+
}, {
77+
"required": ["numberType"]
6978
}
7079
],
7180
"additionalProperties": false

src/Generated/DefinitionPropertyTransfer.php

Lines changed: 15 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Picamator\TransferObject\Transfer\Attribute;
6+
7+
use Attribute;
8+
use BcMath\Number;
9+
10+
/**
11+
* @api
12+
*/
13+
#[Attribute(Attribute::TARGET_CLASS_CONSTANT)]
14+
final readonly class NumberPropertyTypeAttribute implements PropertyTypeAttributeInterface
15+
{
16+
use DataAssertTrait;
17+
18+
public function __construct(private string $typeName)
19+
{
20+
}
21+
22+
public function fromArray(mixed $data): Number
23+
{
24+
/** @var \BcMath\Number $dateTime */
25+
$dateTime = match (true) {
26+
is_string($data) || is_int($data) => new $this->typeName($data),
27+
$data instanceof Number => $data,
28+
default => $this->assertInvalidType($data, $this->typeName),
29+
};
30+
31+
return $dateTime;
32+
}
33+
34+
/**
35+
* @param \BcMath\Number|null $data
36+
*/
37+
public function toArray(mixed $data): ?string
38+
{
39+
return $data?->__toString();
40+
}
41+
42+
public function getInitialValue(): null
43+
{
44+
return null;
45+
}
46+
}

src/TransferGenerator/Definition/DefinitionFactory.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Picamator\TransferObject\TransferGenerator\Definition\Parser\Expander\DateTimeTypePropertyExpander;
1919
use Picamator\TransferObject\TransferGenerator\Definition\Parser\Expander\EnumTypePropertyExpander;
2020
use Picamator\TransferObject\TransferGenerator\Definition\Parser\Expander\NullablePropertyExpander;
21+
use Picamator\TransferObject\TransferGenerator\Definition\Parser\Expander\NumberTypePropertyExpander;
2122
use Picamator\TransferObject\TransferGenerator\Definition\Parser\Expander\PropertyExpanderInterface;
2223
use Picamator\TransferObject\TransferGenerator\Definition\Parser\Expander\ProtectedPropertyExpander;
2324
use Picamator\TransferObject\TransferGenerator\Definition\Parser\Expander\TransferTypePropertyExpander;
@@ -34,6 +35,7 @@
3435
use Picamator\TransferObject\TransferGenerator\Definition\Validator\Property\DateTimeTypePropertyValidator;
3536
use Picamator\TransferObject\TransferGenerator\Definition\Validator\Property\EnumTypePropertyValidator;
3637
use Picamator\TransferObject\TransferGenerator\Definition\Validator\Property\NamePropertyValidator;
38+
use Picamator\TransferObject\TransferGenerator\Definition\Validator\Property\NumberTypePropertyValidator;
3739
use Picamator\TransferObject\TransferGenerator\Definition\Validator\Property\PropertyValidatorInterface;
3840
use Picamator\TransferObject\TransferGenerator\Definition\Validator\Property\RequiredTypePropertyValidator;
3941
use Picamator\TransferObject\TransferGenerator\Definition\Validator\Property\ReservedNamePropertyValidator;
@@ -91,9 +93,15 @@ protected function createPropertyValidators(): ArrayObject
9193
$this->createCollectionTypePropertyValidator(),
9294
$this->createEnumTypePropertyValidator(),
9395
$this->createDateTimeTypePropertyValidator(),
96+
$this->createNumberTypePropertyValidator(),
9497
]);
9598
}
9699

100+
protected function createNumberTypePropertyValidator(): PropertyValidatorInterface
101+
{
102+
return new NumberTypePropertyValidator();
103+
}
104+
97105
protected function createDateTimeTypePropertyValidator(): PropertyValidatorInterface
98106
{
99107
return new DateTimeTypePropertyValidator();
@@ -173,11 +181,17 @@ protected function createPropertyExpander(): PropertyExpanderInterface
173181
->setNextExpander($this->createTransferTypePropertyExpander())
174182
->setNextExpander($this->createEnumTypePropertyExpander())
175183
->setNextExpander($this->createProtectedPropertyExpander())
176-
->setNextExpander($this->createDateTimeTypePropertyExpander());
184+
->setNextExpander($this->createDateTimeTypePropertyExpander())
185+
->setNextExpander($this->createNumberTypePropertyExpander());
177186

178187
return $propertyExpander;
179188
}
180189

190+
protected function createNumberTypePropertyExpander(): PropertyExpanderInterface
191+
{
192+
return new NumberTypePropertyExpander();
193+
}
194+
181195
protected function createDateTimeTypePropertyExpander(): PropertyExpanderInterface
182196
{
183197
return new DateTimeTypePropertyExpander();

src/TransferGenerator/Definition/Enum/DefinitionTypeKeyEnum.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ enum DefinitionTypeKeyEnum: string
1313
case COLLECTION_TYPE = DefinitionPropertyTransfer::COLLECTION_TYPE;
1414
case ENUM_TYPE = DefinitionPropertyTransfer::ENUM_TYPE;
1515
case DATE_TIME_TYPE = DefinitionPropertyTransfer::DATE_TIME_TYPE;
16+
case NUMBER_TYPE = DefinitionPropertyTransfer::NUMBER_TYPE;
1617
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Picamator\TransferObject\TransferGenerator\Definition\Parser\Expander;
6+
7+
use Picamator\TransferObject\Generated\DefinitionEmbeddedTypeTransfer;
8+
use Picamator\TransferObject\Generated\DefinitionPropertyTransfer;
9+
10+
final class NumberTypePropertyExpander extends AbstractPropertyExpander
11+
{
12+
use NamespacePropertyExpanderTrait;
13+
14+
private const string NUMBER_TYPE_KEY = 'numberType';
15+
16+
protected function isApplicable(array $propertyType): bool
17+
{
18+
return $this->getNumberType($propertyType) !== null;
19+
}
20+
21+
protected function handleExpander(array $propertyType, DefinitionPropertyTransfer $propertyTransfer): void
22+
{
23+
$numberType = $this->getNumberType($propertyType) ?? '';
24+
$namespaceTransfer = $this->createDefinitionNamespaceTransfer($numberType);
25+
26+
$typeTransfer = new DefinitionEmbeddedTypeTransfer();
27+
$typeTransfer->name = $namespaceTransfer->alias ?: $namespaceTransfer->baseName;
28+
$typeTransfer->namespace = $namespaceTransfer;
29+
30+
$propertyTransfer->numberType = $typeTransfer;
31+
}
32+
33+
/**
34+
* @param array<string,string|null> $propertyType
35+
*/
36+
private function getNumberType(array $propertyType): ?string
37+
{
38+
$numberType = $propertyType[self::NUMBER_TYPE_KEY] ?? null;
39+
40+
return is_string($numberType) ? $numberType : null;
41+
}
42+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Picamator\TransferObject\TransferGenerator\Definition\Validator\Property;
6+
7+
use BcMath\Number;
8+
use Picamator\TransferObject\Generated\DefinitionPropertyTransfer;
9+
use Picamator\TransferObject\Generated\ValidatorMessageTransfer;
10+
use Picamator\TransferObject\Shared\Validator\ValidatorMessageTrait;
11+
12+
readonly class NumberTypePropertyValidator implements PropertyValidatorInterface
13+
{
14+
use ValidatorMessageTrait;
15+
16+
private const string INVALID_NUMBER_TYPE_ERROR_MESSAGE_TEMPLATE
17+
= 'Property "%s" type "%s" is not a BcMath\Number.';
18+
19+
public function isApplicable(DefinitionPropertyTransfer $propertyTransfer): bool
20+
{
21+
return $propertyTransfer->numberType !== null;
22+
}
23+
24+
public function validate(DefinitionPropertyTransfer $propertyTransfer): ValidatorMessageTransfer
25+
{
26+
$numberClassName = $propertyTransfer->numberType?->namespace?->withoutAlias ?: '';
27+
28+
if ($numberClassName === Number::class) {
29+
return $this->createSuccessMessageTransfer();
30+
}
31+
32+
$errorMessage = $this->getErrorMessage($propertyTransfer);
33+
34+
return $this->createErrorMessageTransfer($errorMessage);
35+
}
36+
37+
private function getErrorMessage(DefinitionPropertyTransfer $propertyTransfer): string
38+
{
39+
return sprintf(
40+
self::INVALID_NUMBER_TYPE_ERROR_MESSAGE_TEMPLATE,
41+
$propertyTransfer->propertyName,
42+
$propertyTransfer->numberType?->namespace->withoutAlias ?? '',
43+
);
44+
}
45+
}

src/TransferGenerator/Generator/Enum/AttributeEnum.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Picamator\TransferObject\Transfer\Attribute\CollectionPropertyTypeAttribute;
1010
use Picamator\TransferObject\Transfer\Attribute\DateTimePropertyTypeAttribute;
1111
use Picamator\TransferObject\Transfer\Attribute\EnumPropertyTypeAttribute;
12+
use Picamator\TransferObject\Transfer\Attribute\NumberPropertyTypeAttribute;
1213
use Picamator\TransferObject\Transfer\Attribute\PropertyTypeAttribute;
1314

1415
enum AttributeEnum: string
@@ -18,5 +19,6 @@ enum AttributeEnum: string
1819
case ENUM_TYPE_ATTRIBUTE = EnumPropertyTypeAttribute::class;
1920
case ARRAY_OBJECT_TYPE_ATTRIBUTE = ArrayObjectPropertyTypeAttribute::class;
2021
case ARRAY_TYPE_ATTRIBUTE = ArrayPropertyTypeAttribute::class;
21-
case DATE_TIME_ATTRIBUTE = DateTimePropertyTypeAttribute::class;
22+
case DATE_TIME_TYPE_ATTRIBUTE = DateTimePropertyTypeAttribute::class;
23+
case NUMBER_TYPE_ATTRIBUTE = NumberPropertyTypeAttribute::class;
2224
}

0 commit comments

Comments
 (0)