Skip to content

Commit

Permalink
Merge pull request #1 from ergebnis/feature/reference-token
Browse files Browse the repository at this point in the history
Enhancement: Implement `ReferenceToken`
  • Loading branch information
localheinz authored Jan 28, 2022
2 parents 3383812 + 6abfa6b commit 074d715
Show file tree
Hide file tree
Showing 10 changed files with 513 additions and 73 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

For a full diff see [`a5ba52c...main`][a5ba52c...main].

### Added

- Added `ReferenceToken` as a value object ([#1]), by [@localheinz]

[a5ba52c...main]: https://github.com/ergebnis/json-pointer/compare/a5ba52c...main

[#1]: https://github.com/ergebnis/json-pointer/pull/1

[@localheinz]: https://github.com/localheinz
62 changes: 61 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,67 @@ composer require ergebnis/json-pointer

## Usage

:bulb: This is a great place for showing a few usage examples!
### ReferenceToken

You can create a `ReferenceToken` from an unescaped `string` value:

```php
<?php

declare(strict_types=1);

use Ergebnis\Json\Pointer;

$referenceToken = Pointer\ReferenceToken::fromUnescapedString('foo/bar');

$referenceToken->toEscapedString(); // 'foo~1bar'
$referenceToken->toUnescapedString(); // 'foo/bar'
```

You can create a `ReferenceToken` from an escaped `string` value:

```php
<?php

declare(strict_types=1);

use Ergebnis\Json\Pointer;

$referenceToken = Pointer\ReferenceToken::fromEscapedString('foo~1bar');

$referenceToken->toEscapedString(); // 'foo~1bar'
$referenceToken->toUnescapedString(); // 'foo/bar'
```

You can create a `ReferenceToken` from an `int` value:

```php
<?php

declare(strict_types=1);

use Ergebnis\Json\Pointer;

$referenceToken = Pointer\ReferenceToken::fromInt(9001);

$referenceToken->toEscapedString(); // '9001'
$referenceToken->toUnescapedString(); // '9001'
```

You can compare `ReferenceToken`s:

```php
<?php

declare(strict_types=1);

use Ergebnis\Json\Pointer;

$one = Pointer\ReferenceToken::fromUnescapedString('foo/bar');
$two = Pointer\ReferenceToken::fromEscapedString('foo~1bar');

$one->equals($two); // true
```

## Changelog

Expand Down
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"type": "library",
"keywords": [
"json",
"pointer"
"pointer",
"rfc6901"
],
"authors": [
{
Expand Down
34 changes: 0 additions & 34 deletions src/Example.php

This file was deleted.

18 changes: 18 additions & 0 deletions src/Exception/Exception.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

/**
* Copyright (c) 2020-2022 Andreas Möller
*
* For the full copyright and license information, please view
* the LICENSE.md file that was distributed with this source code.
*
* @see https://github.com/ergebnis/json-pointer
*/

namespace Ergebnis\Json\Pointer\Exception;

interface Exception extends \Throwable
{
}
33 changes: 33 additions & 0 deletions src/Exception/InvalidReferenceToken.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

/**
* Copyright (c) 2020-2022 Andreas Möller
*
* For the full copyright and license information, please view
* the LICENSE.md file that was distributed with this source code.
*
* @see https://github.com/ergebnis/json-pointer
*/

namespace Ergebnis\Json\Pointer\Exception;

final class InvalidReferenceToken extends \InvalidArgumentException implements Exception
{
public static function fromString(string $value): self
{
return new self(\sprintf(
'Value "%s" does not appear to be a valid JSON Pointer reference token.',
$value,
));
}

public static function fromInt(int $value): self
{
return new self(\sprintf(
'Value "%d" does not appear to be a valid JSON Pointer array index.',
$value,
));
}
}
93 changes: 93 additions & 0 deletions src/ReferenceToken.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php

declare(strict_types=1);

/**
* Copyright (c) 2020-2022 Andreas Möller
*
* For the full copyright and license information, please view
* the LICENSE.md file that was distributed with this source code.
*
* @see https://github.com/ergebnis/json-pointer
*/

namespace Ergebnis\Json\Pointer;

/**
* @psalm-immutable
*
* @see https://datatracker.ietf.org/doc/html/rfc6901
*/
final class ReferenceToken
{
private string $escapedValue;

private function __construct(string $escapedValue)
{
$this->escapedValue = $escapedValue;
}

/**
* @throws Exception\InvalidReferenceToken
*/
public static function fromInt(int $value): self
{
if (0 > $value) {
throw Exception\InvalidReferenceToken::fromInt($value);
}

return new self((string) $value);
}

/**
* @throws Exception\InvalidReferenceToken
*/
public static function fromEscapedString(string $value): self
{
if (1 !== \preg_match('/^(?P<referenceToken>((?P<unescaped>[\x00-\x2E]|[\x30-\x7D]|[\x7F-\x{10FFFF}])|(?P<escaped>~[01]))*)$/u', $value)) {
throw Exception\InvalidReferenceToken::fromString($value);
}

return new self($value);
}

public static function fromUnescapedString(string $value): self
{
return self::fromEscapedString(\str_replace(
[
'~',
'/',
],
[
'~0',
'~1',
],
$value,
));
}

public function toEscapedString(): string
{
return $this->escapedValue;
}

public function toUnescapedString(): string
{
return \str_replace(
[
'~1',
'~0',
],
[
'/',
'~',
],
$this->escapedValue,
);
}

public function equals(self $other): bool
{
return $this->escapedValue === $other->escapedValue;
}
}
37 changes: 0 additions & 37 deletions test/Unit/ExampleTest.php

This file was deleted.

56 changes: 56 additions & 0 deletions test/Unit/Exception/InvalidReferenceTokenTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

declare(strict_types=1);

/**
* Copyright (c) 2020-2022 Andreas Möller
*
* For the full copyright and license information, please view
* the LICENSE.md file that was distributed with this source code.
*
* @see https://github.com/ergebnis/json-pointer
*/

namespace Ergebnis\Json\Pointer\Test\Unit\Exception;

use Ergebnis\Json\Pointer\Exception;
use Ergebnis\Json\Pointer\Test;
use PHPUnit\Framework;

/**
* @internal
*
* @covers \Ergebnis\Json\Pointer\Exception\InvalidReferenceToken
*/
final class InvalidReferenceTokenTest extends Framework\TestCase
{
use Test\Util\Helper;

public function testFromStringReturnsInvalidReferenceToken(): void
{
$value = self::faker()->word();

$exception = Exception\InvalidReferenceToken::fromString($value);

$message = \sprintf(
'Value "%s" does not appear to be a valid JSON Pointer reference token.',
$value,
);

self::assertSame($message, $exception->getMessage());
}

public function testFromIntReturnsInvalidReferenceToken(): void
{
$value = self::faker()->numberBetween();

$exception = Exception\InvalidReferenceToken::fromInt($value);

$message = \sprintf(
'Value "%d" does not appear to be a valid JSON Pointer array index.',
$value,
);

self::assertSame($message, $exception->getMessage());
}
}
Loading

0 comments on commit 074d715

Please sign in to comment.