Skip to content

Commit f310ec5

Browse files
committed
Adding functional API
1 parent d6a9777 commit f310ec5

File tree

7 files changed

+50
-15
lines changed

7 files changed

+50
-15
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ All Notable changes to `bakame/http-strucured-fields` will be documented in this
99
- Support for the `DisplayString` type
1010
- `ByteSequence::tryFromEncoded`
1111
- `Token::tryFromString`
12+
- Adding functional API via `Bakame\Http\StructuredFields\parse` and `Bakame\Http\StructuredFields\build`
1213

1314
### Fixed
1415

README.md

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,20 @@ build and update HTTP Structured Fields in PHP according to the [RFC8941](https:
1313
Once installed you will be able to do the following:
1414

1515
```php
16-
use Bakame\Http\StructuredFields\{InnerList, Item, OuterList, Token};
16+
use Bakame\Http\StructuredFields\InnerList;
17+
use Bakame\Http\StructuredFields\OuterList;
18+
use Bakame\Http\StructuredFields\Token;
1719

1820
//1 - parsing an Accept Header
1921
$headerValue = 'text/html, application/xhtml+xml, application/xml;q=0.9, image/webp, */*;q=0.8';
20-
$field = OuterList::fromHttpValue($headerValue);
22+
$field = parse($headerValue, 'list');
2123
$field[2]->value()->toString(); // returns 'application/xml'
2224
$field[2]->parameter('q'); // returns (float) 0.9
2325
$field[0]->value()->toString(); // returns 'text/html'
2426
$field[0]->parameter('q'); // returns null
2527

2628
//2 - building a Retrofit Cookie Header
27-
echo OuterList::new(
29+
echo build(OuterList::new(
2830
InnerList::fromAssociative(['foo', 'bar'], [
2931
'expire' => $expire,
3032
'path' => '/',
@@ -33,8 +35,7 @@ echo OuterList::new(
3335
'httponly' => true,
3436
'samesite' => Token::fromString('lax'),
3537
])
36-
)
37-
->toHttpValue();
38+
));
3839
// returns ("foo" "bar");expire=@1681504328;path="/";max-age=2500;secure;httponly=?0;samesite=lax
3940
```
4041

@@ -72,13 +73,11 @@ declare(strict_types=1);
7273

7374
require 'vendor/autoload.php';
7475

75-
use Bakame\Http\StructuredFields\Item;
76-
7776
// the raw HTTP field value is given by your application
7877
// via any given framework, package or super global.
7978

8079
$headerLine = 'bar;baz=42'; //the raw header line is a structured field item
81-
$field = Item::fromHttpValue($headerLine);
80+
$field = parse($headerLine, 'item');
8281
$field->value(); // returns Token::fromString('bar); the found token value
8382
$field->parameter('baz'); // returns 42; the value of the parameter or null if the parameter is not defined.
8483
```
@@ -89,9 +88,10 @@ compliant HTTP field string value. To ease integration, the `__toString` method
8988
implemented as an alias to the `toHttpValue` method.
9089

9190
````php
92-
use Bakame\Http\StructuredFields\Item;
91+
use function Bakame\Http\StructuredFields\parse;
92+
use function Bakame\Http\StructuredFields\build;
9393

94-
$field = Item::fromHttpValue('bar; baz=42; secure=?1');
94+
$field = parse('bar; baz=42; secure=?1', 'item');
9595
echo $field->toHttpValue(); // return 'bar;baz=42;secure'
9696
// on serialization the field has been normalized
9797

@@ -101,6 +101,8 @@ echo $field->toHttpValue(); // return 'bar;baz=42;secure'
101101
header('foo: '. $field->toHttpValue());
102102
//or
103103
header('foo: '. $field);
104+
//or
105+
header('foo: '. build($field));
104106
````
105107

106108
All five (5) structured data type as defined in the RFC are provided inside the

composer.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@
3939
"symfony/var-dumper": "^6.4.0"
4040
},
4141
"autoload": {
42+
"files": [
43+
"src/functions.php"
44+
],
4245
"psr-4": {
4346
"Bakame\\Http\\StructuredFields\\": "src/"
4447
}
File renamed without changes.

src/functions.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Bakame\Http\StructuredFields;
6+
7+
if (!function_exists('parse')) {
8+
/**
9+
* Parse a header conform to the HTTP Structured Field RFCs.
10+
*
11+
* @param 'dictionary'|'list'|'item' $type
12+
*
13+
*/
14+
function parse(string $httpValue, string $type): StructuredField
15+
{
16+
return DataType::from($type)->newStructuredField($httpValue);
17+
}
18+
}
19+
20+
if (!function_exists('build')) {
21+
/**
22+
* Build an HTTP header value from a HTTP Structured Field instance.
23+
*/
24+
function build(StructuredField $structuredField): string
25+
{
26+
return $structuredField->toHttpValue();
27+
}
28+
}

tests/Record.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66

77
/**
88
* @phpstan-type RecordData array{
9-
* name:string,
10-
* header_type:string,
11-
* raw:array<string>,
9+
* name: string,
10+
* header_type: 'dictionary'|'list'|'item',
11+
* raw: array<string>,
1212
* canonical?: array<string>,
1313
* must_fail?: bool,
1414
* can_fail?: bool
@@ -18,6 +18,7 @@ final class Record
1818
{
1919
private function __construct(
2020
public readonly string $name,
21+
/** @var 'dictionary'|'list'|'item' */
2122
public readonly string $type,
2223
/** @var array<string> */
2324
public readonly array $raw,

tests/StructuredFieldTestCase.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ public function it_can_pass_http_wg_tests(Record $test): void
2727
$this->expectException(SyntaxError::class);
2828
}
2929

30-
$structuredField = DataType::from($test->type)->newStructuredField(implode(',', $test->raw));
30+
$structuredField = parse(implode(',', $test->raw), $test->type);
3131

3232
if (!$test->mustFail) {
33-
self::assertSame(implode(',', $test->canonical), $structuredField->toHttpValue());
33+
self::assertSame(implode(',', $test->canonical), build($structuredField));
3434
}
3535
}
3636

0 commit comments

Comments
 (0)