Repository navigation
Expand file tree
/
Copy pathStreamFactory.php
More file actions
87 lines (68 loc) · 2.38 KB
/
Copy pathStreamFactory.php
File metadata and controls
87 lines (68 loc) · 2.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
<?php
declare(strict_types=1);
namespace TinyBlocks\Http\Internal\Server\Stream;
use BackedEnum;
use Psr\Http\Message\StreamInterface;
use TinyBlocks\Http\Exceptions\BodyTypeIsUnsupported;
use TinyBlocks\Mapper\Serializable;
use UnitEnum;
final readonly class StreamFactory
{
/**
* Accented text and paths are written as themselves, because the body is read by people as often as by
* parsers, and escaping them only grows the payload.
*/
private const int JSON_FLAGS = (JSON_PRESERVE_ZERO_FRACTION | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
private function __construct(private string $body)
{
}
public static function fromBody(mixed $body): StreamFactory
{
$dataToWrite = match (true) {
$body instanceof Serializable => $body->toJson(),
$body instanceof BackedEnum => StreamFactory::toJsonFrom(body: $body->value),
$body instanceof UnitEnum => $body->name,
is_object($body) => throw BodyTypeIsUnsupported::for(class: $body::class),
is_string($body) => $body,
is_scalar($body) || is_array($body) => StreamFactory::toJsonFrom(body: $body),
default => ''
};
return new StreamFactory(body: $dataToWrite);
}
public static function fromStream(StreamInterface $stream): StreamFactory
{
if ($stream->isSeekable()) {
$stream->rewind();
}
$body = $stream->getContents();
if ($stream->isSeekable()) {
$stream->rewind();
}
return new StreamFactory(body: $body);
}
private static function toJsonFrom(mixed $body): string
{
$encoded = json_encode($body, StreamFactory::JSON_FLAGS);
return $encoded === false ? '' : $encoded;
}
public static function fromEmptyBody(): StreamFactory
{
return new StreamFactory(body: '');
}
public function write(): StreamInterface
{
$resource = fopen('php://memory', 'wb+');
$stream = Stream::from(resource: $resource);
$stream->write($this->body);
$stream->rewind();
return $stream;
}
public function content(): string
{
return $this->body;
}
public function isEmptyContent(): bool
{
return $this->body === '';
}
}