Skip to content

Commit 55e34b8

Browse files
New version
Changed custom Reader interface for `castor/io` ones
1 parent 2b6530c commit 55e34b8

22 files changed

+124
-223
lines changed

README.md

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ as a second argument:
4141
```php
4242
<?php
4343

44-
use function MNC\Http\buffer;
4544
use function MNC\Http\fetch;
45+
use Castor\Io\Eof;
4646

4747
$response = fetch('https://some-domain.example/some-form', [
4848
'method' => 'POST',
@@ -53,8 +53,14 @@ $response = fetch('https://some-domain.example/some-form', [
5353
'body' => json_encode(['data' => 'value'])
5454
]);
5555

56-
// Emit the response to stdout
57-
while (($chunk = $response->body()->read()) !== null) {
56+
// Emit the response to stdout in chunks
57+
while (true) {
58+
$chunk = '';
59+
try {
60+
$response->body()->read(4096, $chunk);
61+
} catch (Eof $e) {
62+
break;
63+
}
5864
echo $chunk;
5965
}
6066
```
@@ -86,7 +92,9 @@ echo $response->status()->reasonPhrase(); // OK
8692
echo $response->headers()->has('content-type'); // true
8793
echo $response->headers()->contains('content-type', 'html'); // true
8894
echo $response->headers()->get('content-type'); // text/html;charset=utf-8
89-
echo $response->body()->read(); // Outputs some bytes from the response body
95+
$bytes = '';
96+
echo $response->body()->read(4096, $bytes); // Allocates reader data into $bytes
97+
echo $bytes; // Outputs some bytes from the response body
9098
```
9199

92100
### Exception Handling
@@ -112,23 +120,23 @@ you most likely will be reacting in different ways to each one of them.
112120
### Body Buffering
113121

114122
When you call the `MNC\Http\Response::body()` method you get an instance of
115-
`MNC\Http\Io\Reader`, which is a very simple interface inspired in golang's
123+
`Castor\Io\Reader`, which is a very simple interface inspired in golang's
116124
`io.Reader`. This interface allows you to read a chunk of bytes until you reach
117125
`EOF` in the data source.
118126

119127
Often times, you don't want to read byte per byte, but get the whole contents
120-
of the body as a string at once. This library provides the `buffer` function
128+
of the body as a string at once. This library provides the `readAll` function
121129
as a convenience for that:
122130

123131
```php
124132
<?php
125133

126-
use function MNC\Http\buffer;
134+
use function Castor\Io\readAll;
127135
use function MNC\Http\fetch;
128136

129137
$response = fetch('https://mnavarro.dev');
130138

131-
echo buffer($response->body()); // Buffers all the contents in memory and emits them.
139+
echo readAll($response->body()); // Buffers all the contents in memory and emits them.
132140
````
133141

134142
Buffering is a very good convenience, but it needs to be used with care, since it could
@@ -148,15 +156,15 @@ in content types like `text/plain`. However, there is big gain in user experienc
148156
when we provide helpers like these in our apis.
149157

150158
This library provides an approach a bit more safe. If the response headers contain the
151-
`application/json` content type, the `MNC\Http\Io\Reader` object of the body is internally
159+
`application/json` content type, the ``Castor\Io\Reader`` object of the body is internally
152160
decorated with a `MNC\Http\Encoding\Json` object. This object implements both the
153-
`Reader` and `JsonDecoder` interfaces. Checking for the former is the safest way of
154-
handling json payloads:
161+
`Reader` interface. Checking for the former is the safest way of handling json
162+
payloads:
155163

156164
```php
157165
<?php
158166

159-
use MNC\Http\Encoding\JsonDecoder;
167+
use MNC\Http\Encoding\Json;
160168
use function MNC\Http\fetch;
161169

162170
$response = fetch('https://api.github.com/users/mnavarrocarter', [
@@ -167,7 +175,7 @@ $response = fetch('https://api.github.com/users/mnavarrocarter', [
167175

168176
$body = $response->body();
169177

170-
if ($body instanceof JsonDecoder) {
178+
if ($body instanceof Json) {
171179
var_dump($body->decode()); // Dumps the json as an array
172180
} else {
173181
// The response body is not json encoded
@@ -236,7 +244,7 @@ api, using the token internally.
236244
```php
237245
<?php
238246

239-
use MNC\Http\Encoding\JsonDecoder;
247+
use MNC\Http\Encoding\Json;
240248
use function MNC\Http\fetch;
241249

242250
$authenticate = static function (string $token) {
@@ -253,7 +261,7 @@ $authenticate = static function (string $token) {
253261
]);
254262

255263
$body = $response->body();
256-
if ($body instanceof JsonDecoder) {
264+
if ($body instanceof Json) {
257265
return $body->decode();
258266
}
259267
return null;
@@ -285,7 +293,7 @@ api client that I need to use.
285293
```php
286294
<?php
287295

288-
use MNC\Http\Encoding\JsonDecoder;
296+
use MNC\Http\Encoding\Json;
289297
use function MNC\Http\fetch;
290298

291299
// We start with an interface, a well defined contract.
@@ -325,7 +333,7 @@ final class FetchApiClient implements ApiClient
325333
]);
326334

327335
$body = $response->body();
328-
if ($body instanceof JsonDecoder) {
336+
if ($body instanceof Json) {
329337
return $body->decode();
330338
}
331339
return null;

composer.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@
2424
}
2525
},
2626
"require": {
27-
"php": "^7.4|^8.0",
28-
"ext-json": "*"
27+
"php": ">=7.4",
28+
"ext-json": "*",
29+
"castor/io": "^0.2.1"
2930
},
3031
"scripts": {
3132
"lint": "php-cs-fixer fix",
@@ -42,6 +43,6 @@
4243
"amphp/http-server": "^2.1",
4344
"amphp/http-server-static-content": "^1.0.6",
4445
"mnavarrocarter/amp-http-router": "^0.1.0",
45-
"friendsofphp/php-cs-fixer": "^2.16"
46+
"friendsofphp/php-cs-fixer": "dev-master"
4647
}
4748
}

examples/arguments.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
use function MNC\Http\buffer;
3+
use function Castor\Io\readAll;
44
use function MNC\Http\fetch;
55

66
require_once __DIR__ . '/../vendor/autoload.php';
@@ -14,4 +14,4 @@
1414
'body' => json_encode(['data' => 'value'])
1515
]);
1616

17-
echo buffer($response->body()); // Emits the response
17+
echo readAll($response->body()); // Emits the response

examples/buffered.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
require_once __DIR__ . '/../vendor/autoload.php';
44

5-
use function MNC\Http\buffer;
5+
use function Castor\Io\readAll;
66
use function MNC\Http\fetch;
77

88
$response = fetch('https://mnavarro.dev');
99

10-
echo buffer($response->body());
10+
echo readAll($response->body());

examples/class.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
use MNC\Http\Encoding\JsonDecoder;
3+
use MNC\Http\Encoding\Json;
44
use function MNC\Http\fetch;
55

66
require_once __DIR__ . '/../vendor/autoload.php';
@@ -42,7 +42,7 @@ public static function authenticate(string $token): FetchApiClient
4242
]);
4343

4444
$body = $response->body();
45-
if ($body instanceof JsonDecoder) {
45+
if ($body instanceof Json) {
4646
return $body->decode();
4747
}
4848
return null;

examples/composition.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
use MNC\Http\Encoding\JsonDecoder;
3+
use MNC\Http\Encoding\Json;
44
use function MNC\Http\fetch;
55

66
$authenticated = static function (string $token) {
@@ -17,7 +17,7 @@
1717
]);
1818

1919
$body = $response->body();
20-
if ($body instanceof JsonDecoder) {
20+
if ($body instanceof Json) {
2121
return $body->decode();
2222
}
2323
return null;

examples/info.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,6 @@
1212
echo $response->headers()->has('content-type'); // true
1313
echo $response->headers()->contains('content-type', 'html'); // true
1414
echo $response->headers()->get('content-type'); // text/html;charset=utf-8
15-
echo $response->body()->read(); // Outputs some bytes from the response body
15+
$bytes = '';
16+
$response->body()->read(4096, $bytes); // Reads data into $bytes
17+
echo $bytes; // Outputs some bytes from the response body

examples/json.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
require_once __DIR__ . '/../vendor/autoload.php';
44

5-
use MNC\Http\Encoding\JsonDecoder;
5+
use MNC\Http\Encoding\Json;
66
use function MNC\Http\fetch;
77

88
$response = fetch('https://api.github.com/users/mnavarrocarter', [
@@ -13,6 +13,6 @@
1313

1414
$body = $response->body();
1515

16-
if ($body instanceof JsonDecoder) {
16+
if ($body instanceof Json) {
1717
var_dump($body->decode()); // Dumps the json as an array
1818
}

examples/simple.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
<?php
22

3+
use Castor\Io\Eof;
34
use function MNC\Http\fetch;
45

56
require_once __DIR__ . '/../vendor/autoload.php';
67

78
$response = fetch('https://mnavarro.dev');
89

9-
while (($chunk = $response->body()->read()) !== null) {
10+
while (true) {
11+
$chunk = '';
12+
try {
13+
$response->body()->read(4096, $chunk);
14+
} catch (Eof $e) {
15+
break;
16+
}
1017
echo $chunk;
1118
}

src/Encoding/Json.php

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@
99

1010
namespace MNC\Http\Encoding;
1111

12+
use Castor\Io\Error;
13+
use function Castor\Io\readAll;
14+
use Castor\Io\Reader;
1215
use JsonException;
13-
use function MNC\Http\buffer;
14-
use MNC\Http\Io\Reader;
15-
use MNC\Http\Io\ReaderError;
1616

1717
/**
1818
* Class Json.
1919
*/
20-
final class Json implements Reader, JsonDecoder
20+
final class Json implements Reader
2121
{
2222
private Reader $reader;
2323

@@ -33,15 +33,18 @@ public function __construct(Reader $reader)
3333
* @return array<mixed, mixed>
3434
*
3535
* @throws JsonException
36-
* @throws ReaderError
36+
* @throws Error
3737
*/
3838
public function decode(): array
3939
{
40-
return json_decode(buffer($this->reader), true, 512, JSON_THROW_ON_ERROR);
40+
return json_decode(readAll($this->reader), true, 512, JSON_THROW_ON_ERROR);
4141
}
4242

43-
public function read(int $bytes = self::DEFAULT_CHUNK_SIZE): ?string
43+
/**
44+
* {@inheritDoc}
45+
*/
46+
public function read(int $length, string &$bytes): int
4447
{
45-
return $this->reader->read($bytes);
48+
return $this->reader->read($length, $bytes);
4649
}
4750
}

0 commit comments

Comments
 (0)