Skip to content

Commit 532bb66

Browse files
authored
Merge pull request #54 from gapple/datetimeinterface
Allow serializing any \DateTimeInterface object as an Item value
2 parents 4a51da7 + 62f14ce commit 532bb66

File tree

6 files changed

+61
-13
lines changed

6 files changed

+61
-13
lines changed

.editorconfig

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ indent_style = space
1111
indent_size = 4
1212

1313
[*.md]
14+
indent_size = 2
1415
trim_trailing_whitespace = false
1516

1617
[*.yml]

readme.md

+30
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,34 @@ Serializer::serializeList(iterable): string;
3939
Serializer::serializeDictionary(object): string;
4040
```
4141

42+
### Special Types
43+
`Serializer` will accept `string` or any `Stringable` object as an Item value,
44+
but will throw a `SerializeException` if it contains any characters outside the
45+
printable ASCII range.
46+
47+
Special Item types must use a decorating class in order to be serialized correctly:
48+
49+
- **Byte Sequences** (`\gapple\StructuredFields\Bytes`)
50+
A string containing binary data.
51+
52+
`Serializer` and `Parser` handle base64 encoding and decoding the provided string.
53+
54+
55+
- **Display Strings** (`\gapple\StructuredFields\DisplayString`)
56+
A string that includes Unicode characters.
57+
58+
`Serializer` and `Parser` handle percent-encoding and decoding non-ascii characters.
59+
60+
61+
- **Tokens** (`\gapple\StructuredFields\Token`)
62+
A short textual word with a restricted character set.
63+
64+
65+
- **Dates** (`\gapple\StructuredFields\Date`)
66+
An integer timestamp
67+
68+
`Serializer` accepts any object that implements `\DateTimeInterface`.
69+
`Parser` will return a `\gapple\StructuredFields\Date` object.
70+
71+
4272
[1]: https://www.rfc-editor.org/rfc/rfc9651.html

src/Date.php

+8-3
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,19 @@
44

55
namespace gapple\StructuredFields;
66

7-
class Date
7+
class Date extends \DateTimeImmutable
88
{
9-
public function __construct(private readonly int $value)
9+
public function __construct(int $timestamp)
1010
{
11+
parent::__construct("@{$timestamp}");
1112
}
1213

14+
/**
15+
* @deprecated in 2.3.0 and will be removed from 3.0.0. Use Date::getTimestamp() instead.
16+
* @codeCoverageIgnore
17+
*/
1318
public function toInt(): int
1419
{
15-
return $this->value;
20+
return $this->getTimestamp();
1621
}
1722
}

src/Serializer.php

+6-6
Original file line numberDiff line numberDiff line change
@@ -153,14 +153,14 @@ private static function serializeBareItem(mixed $value): string
153153
return self::serializeDecimal($value);
154154
} elseif (is_bool($value)) {
155155
return self::serializeBoolean($value);
156-
} elseif ($value instanceof Token) {
157-
return self::serializeToken($value);
156+
} elseif ($value instanceof \DateTimeInterface) {
157+
return self::serializeDate($value);
158158
} elseif ($value instanceof Bytes) {
159159
return self::serializeByteSequence($value);
160-
} elseif ($value instanceof Date) {
161-
return self::serializeDate($value);
162160
} elseif ($value instanceof DisplayString) {
163161
return self::serializeDisplayString($value);
162+
} elseif ($value instanceof Token) {
163+
return self::serializeToken($value);
164164
} elseif (is_string($value) || $value instanceof \Stringable) {
165165
return self::serializeString((string) $value);
166166
}
@@ -260,9 +260,9 @@ private static function serializeParameters(object $value): string
260260
return $returnValue;
261261
}
262262

263-
private static function serializeDate(Date $value): string
263+
private static function serializeDate(\DateTimeInterface $value): string
264264
{
265-
return '@' . self::serializeInteger($value->toInt());
265+
return '@' . self::serializeInteger($value->getTimestamp());
266266
}
267267

268268
private static function serializeKey(string $value): string

tests/DateTest.php

+14-2
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,47 @@
22

33
namespace gapple\Tests\StructuredFields;
44

5+
use gapple\StructuredFields\Item;
6+
57
/**
68
* Additional Date parsing and serializing tests.
79
*/
810
class DateTest extends RulesetTestBase
911
{
1012
use ParsingRulesetTrait;
13+
use SerializingRulesetTrait;
1114

1215
/**
1316
* {@inheritdoc}
1417
*/
1518
protected static function rulesetDataProvider(): array
1619
{
1720
return [
18-
'date - large int' => [
21+
'large int' => [
1922
Rule::fromArray([
2023
'name' => 'date - large int',
2124
'raw' => ['@1234567890123456'],
2225
'header_type' => 'item',
2326
'must_fail' => true,
2427
]),
2528
],
26-
'date - hexadecimal' => [
29+
'hexadecimal' => [
2730
Rule::fromArray([
2831
'name' => 'date - hexadecimal',
2932
'raw' => ['@0x62EB2779'],
3033
'header_type' => 'item',
3134
'must_fail' => true,
3235
]),
3336
],
37+
// Serialize any \DateTimeInterface object.
38+
'DateTimeInterface' => [
39+
Rule::fromArray([
40+
'name' => 'date - DateTimeInterface',
41+
'header_type' => 'item',
42+
'expected' => new Item(new \DateTimeImmutable('@629528400')),
43+
'canonical' => ['@629528400'],
44+
]),
45+
],
3446
];
3547
}
3648
}

tests/Httpwg/HttpwgRuleExpectedConverter.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,9 @@ private static function innerList(array $innerList): InnerList
122122
*
123123
* @param ExpectedBareValue $data
124124
* The expected bare value.
125-
* @return bool|int|float|string|Bytes|Date|DisplayString|Token
125+
* @return bool|int|float|string|Bytes|\DateTimeInterface|DisplayString|Token
126126
*/
127-
private static function value($data)
127+
private static function value($data): mixed
128128
{
129129
if (!is_object($data)) {
130130
return $data;

0 commit comments

Comments
 (0)