Skip to content

Commit

Permalink
feat: transformation from Stringable to int, float, and bool by cas…
Browse files Browse the repository at this point in the history
…ting (#218)
  • Loading branch information
priyadi authored Oct 10, 2024
1 parent 8f28fa6 commit 7798c35
Show file tree
Hide file tree
Showing 11 changed files with 161 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
* chore: rector run
* perf: object mapper resolver cache prewarming
* fix: terms
* feat: transformation from `Stringable` to int, float, and bool by casting

## 1.9.4

Expand Down
31 changes: 30 additions & 1 deletion src/Transformer/Implementation/ObjectToStringTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,13 @@
use Rekalogika\Mapper\Exception\InvalidArgumentException;
use Rekalogika\Mapper\Transformer\TransformerInterface;
use Rekalogika\Mapper\Transformer\TypeMapping;
use Rekalogika\Mapper\Util\TypeCheck;
use Rekalogika\Mapper\Util\TypeFactory;
use Symfony\Component\PropertyInfo\Type;

/**
* @todo rename class to ObjectToScalarTransformer
*/
final readonly class ObjectToStringTransformer implements TransformerInterface
{
#[\Override]
Expand All @@ -31,7 +35,17 @@ public function transform(
Context $context,
): mixed {
if ($source instanceof \Stringable) {
return (string) $source;
if (TypeCheck::isString($targetType)) {
return (string) $source;
} elseif (TypeCheck::isInt($targetType)) {
return (int) (string) $source;
} elseif (TypeCheck::isFloat($targetType)) {
return (float) (string) $source;
} elseif (TypeCheck::isBool($targetType)) {
return (bool) (string) $source;
} else {
return (string) $source;
}
} elseif ($source instanceof \BackedEnum) {
return $source->value;
} elseif ($source instanceof \UnitEnum) {
Expand All @@ -49,6 +63,21 @@ public function getSupportedTransformation(): iterable
TypeFactory::string(),
);

yield new TypeMapping(
TypeFactory::objectOfClass(\Stringable::class),
TypeFactory::int(),
);

yield new TypeMapping(
TypeFactory::objectOfClass(\Stringable::class),
TypeFactory::float(),
);

yield new TypeMapping(
TypeFactory::objectOfClass(\Stringable::class),
TypeFactory::bool(),
);

yield new TypeMapping(
TypeFactory::objectOfClass(\UnitEnum::class),
TypeFactory::string(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
use Rekalogika\Mapper\Util\TypeFactory;
use Symfony\Component\PropertyInfo\Type;

/**
* @todo rename class to StringToEnumTransformer
*/
final readonly class StringToBackedEnumTransformer implements TransformerInterface
{
#[\Override]
Expand Down
20 changes: 16 additions & 4 deletions tests/config/rekalogika-mapper/generated-mappings.php
Original file line number Diff line number Diff line change
Expand Up @@ -358,21 +358,33 @@
);

$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/ObjectEnumStringMappingTest.php on line 38
// tests/src/IntegrationTest/ObjectEnumStringMappingTest.php on line 57
source: \Rekalogika\Mapper\Tests\Fixtures\EnumAndStringable\ObjectWithEnumProperty::class,
target: \Rekalogika\Mapper\Tests\Fixtures\EnumAndStringable\ObjectWithStringProperty::class
);

$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/ObjectEnumStringMappingTest.php on lines 47, 58, 67
// tests/src/IntegrationTest/ObjectEnumStringMappingTest.php on line 49
source: \Rekalogika\Mapper\Tests\Fixtures\EnumAndStringable\ObjectWithNumericStringableProperty::class,
target: \Rekalogika\Mapper\Tests\Fixtures\EnumAndStringableDto\ObjectWithFloatPropertyDto::class
);

$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/ObjectEnumStringMappingTest.php on line 41
source: \Rekalogika\Mapper\Tests\Fixtures\EnumAndStringable\ObjectWithNumericStringableProperty::class,
target: \Rekalogika\Mapper\Tests\Fixtures\EnumAndStringableDto\ObjectWithIntegerPropertyDto::class
);

$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/ObjectEnumStringMappingTest.php on lines 66, 77, 86
source: \Rekalogika\Mapper\Tests\Fixtures\EnumAndStringable\ObjectWithStringProperty::class,
target: \Rekalogika\Mapper\Tests\Fixtures\EnumAndStringable\ObjectWithEnumProperty::class
);

$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/ObjectEnumStringMappingTest.php on line 30
// tests/src/IntegrationTest/ObjectEnumStringMappingTest.php on line 33
source: \Rekalogika\Mapper\Tests\Fixtures\EnumAndStringable\ObjectWithStringableProperty::class,
target: \Rekalogika\Mapper\Tests\Fixtures\EnumAndStringableDto\ObjectWithStringablePropertyDto::class
target: \Rekalogika\Mapper\Tests\Fixtures\EnumAndStringableDto\ObjectWithStringPropertyDto::class
);

$mappingCollection->addObjectMapping(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

/*
* This file is part of rekalogika/mapper package.
*
* (c) Priyadi Iman Nurcahyo <https://rekalogika.dev>
*
* For the full copyright and license information, please view the LICENSE file
* that was distributed with this source code.
*/

namespace Rekalogika\Mapper\Tests\Fixtures\EnumAndStringable;

class ObjectImplementingNumericStringable implements \Stringable
{
#[\Override]
public function __toString(): string
{
return '123456.789';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

/*
* This file is part of rekalogika/mapper package.
*
* (c) Priyadi Iman Nurcahyo <https://rekalogika.dev>
*
* For the full copyright and license information, please view the LICENSE file
* that was distributed with this source code.
*/

namespace Rekalogika\Mapper\Tests\Fixtures\EnumAndStringable;

class ObjectWithNumericStringableProperty
{
public ObjectImplementingNumericStringable $property;

public function __construct()
{
$this->property = new ObjectImplementingNumericStringable();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@

class ObjectWithStringableProperty
{
public ObjectImplementingStringable $stringable;
public ObjectImplementingStringable $property;

public function __construct()
{
$this->stringable = new ObjectImplementingStringable();
$this->property = new ObjectImplementingStringable();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

namespace Rekalogika\Mapper\Tests\Fixtures\EnumAndStringableDto;

class ObjectWithStringablePropertyDto
class ObjectWithFloatPropertyDto
{
public ?string $stringable = null;
public ?float $property = null;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

/*
* This file is part of rekalogika/mapper package.
*
* (c) Priyadi Iman Nurcahyo <https://rekalogika.dev>
*
* For the full copyright and license information, please view the LICENSE file
* that was distributed with this source code.
*/

namespace Rekalogika\Mapper\Tests\Fixtures\EnumAndStringableDto;

class ObjectWithIntegerPropertyDto
{
public ?int $property = null;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

/*
* This file is part of rekalogika/mapper package.
*
* (c) Priyadi Iman Nurcahyo <https://rekalogika.dev>
*
* For the full copyright and license information, please view the LICENSE file
* that was distributed with this source code.
*/

namespace Rekalogika\Mapper\Tests\Fixtures\EnumAndStringableDto;

class ObjectWithStringPropertyDto
{
public ?string $property = null;
}
25 changes: 22 additions & 3 deletions tests/src/IntegrationTest/ObjectEnumStringMappingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,39 @@
use Rekalogika\Mapper\Exception\InvalidArgumentException;
use Rekalogika\Mapper\Tests\Common\FrameworkTestCase;
use Rekalogika\Mapper\Tests\Fixtures\EnumAndStringable\ObjectWithEnumProperty;
use Rekalogika\Mapper\Tests\Fixtures\EnumAndStringable\ObjectWithNumericStringableProperty;
use Rekalogika\Mapper\Tests\Fixtures\EnumAndStringable\ObjectWithStringableProperty;
use Rekalogika\Mapper\Tests\Fixtures\EnumAndStringable\ObjectWithStringProperty;
use Rekalogika\Mapper\Tests\Fixtures\EnumAndStringable\SomeBackedEnum;
use Rekalogika\Mapper\Tests\Fixtures\EnumAndStringable\SomeEnum;
use Rekalogika\Mapper\Tests\Fixtures\EnumAndStringableDto\ObjectWithStringablePropertyDto;
use Rekalogika\Mapper\Tests\Fixtures\EnumAndStringableDto\ObjectWithFloatPropertyDto;
use Rekalogika\Mapper\Tests\Fixtures\EnumAndStringableDto\ObjectWithIntegerPropertyDto;
use Rekalogika\Mapper\Tests\Fixtures\EnumAndStringableDto\ObjectWithStringPropertyDto;

class ObjectEnumStringMappingTest extends FrameworkTestCase
{
public function testStringableToString(): void
{
$object = new ObjectWithStringableProperty();
$result = $this->mapper->map($object, ObjectWithStringablePropertyDto::class);
$result = $this->mapper->map($object, ObjectWithStringPropertyDto::class);

$this->assertEquals('foo', $result->stringable);
$this->assertEquals('foo', $result->property);
}

public function testStringableToInteger(): void
{
$object = new ObjectWithNumericStringableProperty();
$result = $this->mapper->map($object, ObjectWithIntegerPropertyDto::class);

$this->assertEquals(123456, $result->property);
}

public function testStringableToFloat(): void
{
$object = new ObjectWithNumericStringableProperty();
$result = $this->mapper->map($object, ObjectWithFloatPropertyDto::class);

$this->assertEquals(123456.789, $result->property);
}

public function testEnumToString(): void
Expand Down

0 comments on commit 7798c35

Please sign in to comment.