Skip to content

Commit

Permalink
float/double add third parameter to define fixed numbers of decimals.…
Browse files Browse the repository at this point in the history
… In json this param force to cast the result as a string. fix #1415
  • Loading branch information
riccardonar authored and goetas committed Jan 6, 2023
1 parent ebe4ee3 commit 0a242c4
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 10 deletions.
5 changes: 5 additions & 0 deletions doc/reference/annotations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,11 @@ Available Types:
| | Rounding Mode. |
| | (HALF_UP, HALF_DOWN, HALF_EVEN HALF_ODD) |
+------------------------------------------------------------+--------------------------------------------------+
| double<2, 'HALF_DOWN', 2> or float<2, 'HALF_DOWN', 2> | Primitive double with percision, |
| double<2, 'HALF_DOWN', 3> or float<2, 'HALF_DOWN', 3> | Rounding Mode and fixed decimals (default 1). |
| | (HALF_UP, HALF_DOWN, HALF_EVEN HALF_ODD) |
| | NOTE: for json the value is cast to string |
+------------------------------------------------------------+--------------------------------------------------+
| string | Primitive string |
+------------------------------------------------------------+--------------------------------------------------+
| array | An array with arbitrary keys, and values. |
Expand Down
15 changes: 10 additions & 5 deletions src/JsonSerializationVisitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,20 @@ public function visitInteger(int $data, array $type)
*/
public function visitDouble(float $data, array $type)
{
$dataResult = $data;
$percision = $type['params'][0] ?? null;
if (!is_int($percision)) {
return $data;
if ($percision) {
$roundMode = $type['params'][1] ?? null;
$roundMode = $this->mapRoundMode($roundMode);
$dataResult = round($dataResult, $percision, $roundMode);
}

$roundMode = $type['params'][1] ?? null;
$roundMode = $this->mapRoundMode($roundMode);
$decimalsNumbers = $type['params'][2] ?? null;
if ($decimalsNumbers !== null) {
$dataResult = number_format($dataResult, $decimalsNumbers, '.', '');
}

return round($data, $percision, $roundMode);
return $dataResult;
}

/**
Expand Down
18 changes: 15 additions & 3 deletions src/XmlSerializationVisitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -179,14 +179,26 @@ public function visitInteger(int $data, array $type)
*/
public function visitDouble(float $data, array $type)
{
$dataResult = $data;
$percision = $type['params'][0] ?? null;
if (is_int($percision)) {
if ($percision) {
$roundMode = $type['params'][1] ?? null;
$roundMode = $this->mapRoundMode($roundMode);
$data = round($data, $percision, $roundMode);
$dataResult = round($dataResult, $percision, $roundMode);
}

return $this->document->createTextNode(var_export((float) $data, true));
$decimalsNumbers = $type['params'][2] ?? null;
if ($decimalsNumbers === null) {
$parts = explode('.', (string) $dataResult);
if (count($parts) < 2 || !$parts[1]) {
$decimalsNumbers = 1;
}
}
if ($decimalsNumbers !== null) {
$dataResult = number_format($dataResult, $decimalsNumbers, '.', '');
}

return $this->document->createTextNode((string) $dataResult);
}

/**
Expand Down
44 changes: 43 additions & 1 deletion tests/Fixtures/ObjectWithFloatProperty.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,45 @@ class ObjectWithFloatProperty
#[Type(name: 'double<2, "HALF_UP">')]
private $floatingPointHalfUp;

/**
* @Type("double<2,null,2>")
* @var float
*/
#[Type(name: 'double<2, null, 2>')]
private $floatingPointFixedDecimals;

/**
* @Type("double<2,null,1>")
* @var float
*/
#[Type(name: 'double<2, null, 1>')]
private $floatingPointFixedDecimalsLess;

/**
* @Type("double<2,null,3>")
* @var float
*/
#[Type(name: 'double<2, null, 3>')]
private $floatingPointFixedDecimalsMore;

public function __construct(
float $floatingPointUnchanged,
float $floatingPointHalfDown,
float $floatingPointHalfEven,
float $floatingPointHalfOdd,
float $floatingPointHalfUp
float $floatingPointHalfUp,
float $floatingPointFixedDecimals,
float $floatingPointFixedDecimalsLess,
float $floatingPointFixedDecimalsMore
) {
$this->floatingPointUnchanged = $floatingPointUnchanged;
$this->floatingPointHalfDown = $floatingPointHalfDown;
$this->floatingPointHalfEven = $floatingPointHalfEven;
$this->floatingPointHalfOdd = $floatingPointHalfOdd;
$this->floatingPointHalfUp = $floatingPointHalfUp;
$this->floatingPointFixedDecimals = $floatingPointFixedDecimals;
$this->floatingPointFixedDecimalsLess = $floatingPointFixedDecimalsLess;
$this->floatingPointFixedDecimalsMore = $floatingPointFixedDecimalsMore;
}

public function getFloatingPointUnchanged(): float
Expand All @@ -81,4 +108,19 @@ public function getFloatingPointHalfUp(): float
{
return $this->floatingPointHalfUp;
}

public function getFloatingPointFixedDecimals(): float
{
return $this->floatingPointFixedDecimals;
}

public function getFloatingPointFixedDecimalsLess(): float
{
return $this->floatingPointFixedDecimalsLess;
}

public function getFloatingPointFixedDecimalsMore(): float
{
return $this->floatingPointFixedDecimalsMore;
}
}
8 changes: 7 additions & 1 deletion tests/Serializer/JsonSerializationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,9 @@ public function testSerialisationWithPercisionForFloat(): void
1.555,
1.15,
1.15,
1.555,
1.5,
1.555,
1.555
);

Expand All @@ -464,7 +467,10 @@ public function testSerialisationWithPercisionForFloat(): void
. '"floating_point_half_down":1.55,'
. '"floating_point_half_even":1.2,'
. '"floating_point_half_odd":1.1,'
. '"floating_point_half_up":1.56'
. '"floating_point_half_up":1.56,'
. '"floating_point_fixed_decimals":"1.50",'
. '"floating_point_fixed_decimals_less":"1.6",'
. '"floating_point_fixed_decimals_more":"1.560"'
. '}',
$result
);
Expand Down
6 changes: 6 additions & 0 deletions tests/Serializer/XmlSerializationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,9 @@ public function testSerialisationWithPercisionForFloat(): void
1.555,
1.15,
1.15,
1.555,
1.5,
1.555,
1.555
);

Expand All @@ -590,6 +593,9 @@ public function testSerialisationWithPercisionForFloat(): void
<floating_point_half_even>1.2</floating_point_half_even>
<floating_point_half_odd>1.1</floating_point_half_odd>
<floating_point_half_up>1.56</floating_point_half_up>
<floating_point_fixed_decimals>1.50</floating_point_fixed_decimals>
<floating_point_fixed_decimals_less>1.6</floating_point_fixed_decimals_less>
<floating_point_fixed_decimals_more>1.560</floating_point_fixed_decimals_more>
</result>',
$result
);
Expand Down

0 comments on commit 0a242c4

Please sign in to comment.