Skip to content

Commit

Permalink
Add handling for Date type
Browse files Browse the repository at this point in the history
  • Loading branch information
gapple committed Jan 16, 2023
1 parent da0fd6f commit f63dfaa
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 4 deletions.
18 changes: 18 additions & 0 deletions src/Date.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace gapple\StructuredFields;

class Date
{
private $value;

public function __construct(int $value)
{
$this->value = $value;
}

public function toInt(): int
{
return $this->value;
}
}
16 changes: 15 additions & 1 deletion src/Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ private static function doParseItem(string &$string): array
/**
* @param string $string
*
* @return bool|float|int|string|\gapple\StructuredFields\Bytes|\gapple\StructuredFields\Token
* @return bool|float|int|string|\gapple\StructuredFields\Bytes|\gapple\StructuredFields\Token|\gapple\StructuredFields\Date
*/
private static function parseBareItem(string &$string)
{
Expand All @@ -167,6 +167,8 @@ private static function parseBareItem(string &$string)
$value = self::parseByteSequence($string);
} elseif ($string[0] == '?') {
$value = self::parseBoolean($string);
} elseif ($string[0] == '@') {
$value = self::parseDate($string);
} elseif (preg_match('/^([a-z*])/i', $string)) {
$value = self::parseToken($string);
} else {
Expand Down Expand Up @@ -307,4 +309,16 @@ private static function parseByteSequence(string &$string): Bytes

throw new ParseException('Invalid character in byte sequence');
}

private static function parseDate(string &$string): Date
{
$string = substr($string, 1);
$value = self::parseNumber($string);

if (is_int($value)) {
return new Date($value);
}

throw new ParseException("Invalid Date format");
}
}
7 changes: 7 additions & 0 deletions src/Serializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ private static function serializeBareItem($value): string
return self::serializeToken($value);
} elseif ($value instanceof Bytes) {
return self::serializeByteSequence($value);
} elseif ($value instanceof Date) {
return self::serializeDate($value);
} elseif (is_string($value) || (is_object($value) && method_exists($value, '__toString'))) {
return self::serializeString($value);
}
Expand Down Expand Up @@ -162,6 +164,11 @@ private static function serializeParameters(object $value): string
return $returnValue;
}

private static function serializeDate(Date $value): string
{
return '@' . self::serializeInteger($value->toInt());
}

private static function serializeKey(string $value): string
{
if (!preg_match('/^[a-z*][a-z0-9.*_-]*$/', $value)) {
Expand Down
80 changes: 80 additions & 0 deletions tests/DateTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

namespace gapple\Tests\StructuredFields;

use gapple\StructuredFields\Date;

/**
* Test Date parsing and serializing.
*
* @todo Replace with httpwg test cases when available
* https://github.com/httpwg/structured-field-tests/pull/83
*/
class DateTest extends RulesetTest
{
protected function rulesetDataProvider(): array
{
$rules = [
[
"name" => "date - 1970-01-01 00:00:00",
"raw" => ["@0"],
"header_type" => "item",
"expected" => [new Date(0), new \stdClass()],
],
[
"name" => "date - 2022-08-04 01:57:13",
"raw" => ["@1659578233"],
"header_type" => "item",
"expected" => [new Date(1659578233), new \stdClass()],
],
[
"name" => "date - 1917-05-30 22:02:47",
"raw" => ["@-1659578233"],
"header_type" => "item",
"expected" => [new Date(-1659578233), new \stdClass()],
],
[
"name" => "date - 2^31",
"raw" => ["@2147483648"],
"header_type" => "item",
"expected" => [new Date(2147483648), new \stdClass()],
],
[
"name" => "date - 2^32",
"raw" => ["@4294967296"],
"header_type" => "item",
"expected" => [new Date(4294967296), new \stdClass()],
],
[
"name" => "date - decimal",
"raw" => ["@1659578233.12"],
"header_type" => "item",
"must_fail" => true,
],
[
"name" => "date - large int",
"raw" => ["@1234567890123456"],
"header_type" => "item",
"must_fail" => true,
],
[
"name" => "date - hexadecimal",
"raw" => ["@0x62EB2779"],
"header_type" => "item",
"must_fail" => true,
],
];

$dataset = [];
foreach ($rules as $rule) {
$rule = (object) $rule;

$rule->must_fail = $rule->must_fail ?? false;
$rule->can_fail = $rule->can_fail ?? false;

$dataset[$rule->name] = [$rule];
}

return $dataset;
}
}
9 changes: 6 additions & 3 deletions tests/RulesetTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace gapple\Tests\StructuredFields;

use gapple\StructuredFields\Bytes;
use gapple\StructuredFields\Date;
use gapple\StructuredFields\ParseException;
use gapple\StructuredFields\Parser;
use gapple\StructuredFields\SerializeException;
Expand Down Expand Up @@ -35,7 +36,7 @@ abstract class RulesetTest extends TestCase
*/
protected $skipSerializingRules = [];

private function rulesetDataProvider()
protected function rulesetDataProvider(): array
{
$path = __DIR__ . '/../vendor/httpwg/structured-field-tests/' . $this->ruleset . '.json';
if (!file_exists($path)) {
Expand Down Expand Up @@ -77,7 +78,7 @@ private function rulesetDataProvider()
return $dataset;
}

public function parseRulesetDataProvider()
public function parseRulesetDataProvider(): array
{
return array_filter(
static::rulesetDataProvider(),
Expand All @@ -87,7 +88,7 @@ function ($params) {
);
}

public function serializeRulesetDataProvider()
public function serializeRulesetDataProvider(): array
{
return array_filter(
static::rulesetDataProvider(),
Expand Down Expand Up @@ -284,6 +285,8 @@ private static function convertValue($data)
return new Token($data->value);
case 'binary':
return new Bytes(Base32::decodeUpper($data->value));
case 'date':
return new Date($data->value);
}
}

Expand Down

0 comments on commit f63dfaa

Please sign in to comment.