Skip to content

Commit efbcf68

Browse files
committed
Improve Temporal set string formatting
1 parent d33ec80 commit efbcf68

4 files changed

Lines changed: 62 additions & 26 deletions

File tree

src/Event.php

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
use JsonSerializable;
88

9+
use function explode;
10+
911
final class Event implements HasIdentifiers, JsonSerializable
1012
{
1113
private function __construct(
@@ -24,25 +26,34 @@ public static function at(Time $time, Identifiers|string $identifier = new Ident
2426
return new self($time, !$identifier instanceof Identifiers ? new Identifiers($identifier) : $identifier);
2527
}
2628

29+
/**
30+
* @see TimeFormat::decode()
31+
*
32+
* @throws InvalidTime|TemporalException
33+
*/
34+
public static function fromFormat(string $value, TimeFormat $format = TimeFormat::Iso8601): self
35+
{
36+
[$time, $identifiers] = explode(';', $value, 2) + [1 => ''];
37+
38+
return new self(Time::fromFormat($time, $format), Identifiers::fromFormat($identifiers));
39+
}
40+
2741
/**
2842
* @see IntervalFormat::encode()
2943
*
3044
* @return non-empty-string
3145
*/
3246
public function format(TimeFormat $format = TimeFormat::Iso8601): string
3347
{
34-
return $format->encode($this->at).' -> '.$this->identifier->formatted();
48+
return $format->encode($this->at).';'.$this->identifier->formatted();
3549
}
3650

3751
/**
38-
* @return array{at: Time, identifiers: Identifiers}
52+
* @return non-empty-string
3953
*/
40-
public function jsonSerialize(): mixed
54+
public function jsonSerialize(): string
4155
{
42-
return [
43-
'at' => $this->at,
44-
'identifiers' => $this->identifier,
45-
];
56+
return $this->format();
4657
}
4758

4859
public function identifiers(): Identifiers

src/Identifiers.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@
1313
use function array_filter;
1414
use function array_keys;
1515
use function count;
16+
use function explode;
1617
use function implode;
1718
use function in_array;
1819
use function is_string;
20+
use function preg_match;
1921
use function sort;
2022
use function trim;
2123

@@ -93,6 +95,16 @@ private static function filterIdentifiers(Identifiers|HasIdentifiers|iterable|st
9395
return $filteredData;
9496
}
9597

98+
/**
99+
* @throws TemporalException
100+
*/
101+
public static function fromFormat(string $value): self
102+
{
103+
$value = trim($value);
104+
105+
return '' === $value ? new self() : new self(explode(',', $value)); /* @phpstan-ignore-line */
106+
}
107+
96108
/**
97109
* @param InputIdentifiers ...$others
98110
*
@@ -238,6 +250,8 @@ public function __serialize(): array
238250

239251
/**
240252
* @param array{0: array{identifiers: list<non-empty-string>}, 1: array{}} $data
253+
*
254+
* @throws TemporalException
241255
*/
242256
public function __unserialize(array $data): void
243257
{

src/Task.php

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
use JsonSerializable;
88

9+
use function explode;
10+
911
final readonly class Task implements HasIdentifiers, JsonSerializable
1012
{
1113
private function __construct(
@@ -30,14 +32,23 @@ public function identifiers(): Identifiers
3032
}
3133

3234
/**
33-
* @return array{period: Interval, identifiers: Identifiers}
35+
* @return non-empty-string
3436
*/
35-
public function jsonSerialize(): array
37+
public function jsonSerialize(): string
3638
{
37-
return [
38-
'period' => $this->period,
39-
'identifiers' => $this->identifier,
40-
];
39+
return $this->format();
40+
}
41+
42+
/**
43+
* @see IntervalFormat::decode()
44+
*
45+
* @throws InvalidInterval|TemporalException
46+
*/
47+
public static function fromFormat(string $value, IntervalFormat $format = IntervalFormat::Iso8601StartDuration, ?Unit $unit = null): self
48+
{
49+
[$period, $identifiers] = explode(';', $value, 2) + [1 => ''];
50+
51+
return new self(Interval::fromFormat($period, $format, $unit), Identifiers::fromFormat($identifiers));
4152
}
4253

4354
/**
@@ -47,7 +58,7 @@ public function jsonSerialize(): array
4758
*/
4859
public function format(IntervalFormat $format = IntervalFormat::Iso8601StartDuration, ?Unit $unit = null): string
4960
{
50-
return $format->encode($this->period, $unit).' => '.$this->identifier->formatted();
61+
return $format->encode($this->period, $unit).';'.$this->identifier->formatted();
5162
}
5263

5364
public function equals(Task $other): bool

src/TaskSetTest.php

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ public function test_union_merges_overlapping_tasks(): void
3939
$result = $set->union([$this->task('B', Interval::between(Time::at(11), Time::at(14)))]);
4040

4141
self::assertEquals([
42-
'[09:00:00,11:00:00) => A',
43-
'[11:00:00,12:00:00) => A,B',
44-
'[12:00:00,14:00:00) => B',
42+
'[09:00:00,11:00:00);A',
43+
'[11:00:00,12:00:00);A,B',
44+
'[12:00:00,14:00:00);B',
4545
], $this->format($result));
4646
}
4747

@@ -59,8 +59,8 @@ public function test_intersect_returns_only_shared_intervals(): void
5959
$result = $a->intersect([$b]);
6060

6161
self::assertEquals([
62-
'[10:00:00,12:00:00) => A',
63-
'[13:00:00,14:00:00) => B,A',
62+
'[10:00:00,12:00:00);A',
63+
'[13:00:00,14:00:00);B,A',
6464
], $this->format($result));
6565
}
6666

@@ -83,7 +83,7 @@ public function test_gaps_detect_missing_time(): void
8383

8484
$gaps = $set->gaps();
8585

86-
self::assertEquals(['[11:00:00,13:00:00) => '], $this->format($gaps));
86+
self::assertEquals(['[11:00:00,13:00:00);'], $this->format($gaps));
8787
}
8888

8989
public function test_difference_returns_the_source_set_if_there_is_no_intersection(): void
@@ -103,8 +103,8 @@ public function test_difference_removes_middle_overlap(): void
103103
$result = $a->difference($b);
104104

105105
self::assertEquals([
106-
'[09:00:00,10:00:00) => A',
107-
'[11:00:00,12:00:00) => A',
106+
'[09:00:00,10:00:00);A',
107+
'[11:00:00,12:00:00);A',
108108
], $this->format($result));
109109
}
110110

@@ -115,7 +115,7 @@ public function test_difference_with_no_overlap_returns_original(): void
115115
$result = $a->difference($b);
116116

117117
self::assertEquals([
118-
'[09:00:00,12:00:00) => A',
118+
'[09:00:00,12:00:00);A',
119119
], $this->format($result));
120120
}
121121

@@ -140,8 +140,8 @@ public function test_difference_splits_multiple_tasks(): void
140140
$result = $a->difference($b);
141141

142142
self::assertEquals([
143-
'[09:00:00,10:00:00) => A',
144-
'[12:00:00,13:00:00) => A2',
143+
'[09:00:00,10:00:00);A',
144+
'[12:00:00,13:00:00);A2',
145145
], $this->format($result));
146146
}
147147

@@ -164,7 +164,7 @@ public function test_difference_edge_touching_boundaries(): void
164164
$result = $a->difference($b);
165165

166166
self::assertEquals([
167-
'[09:00:00,12:00:00) => A',
167+
'[09:00:00,12:00:00);A',
168168
], $this->format($result));
169169
}
170170

0 commit comments

Comments
 (0)