diff --git a/README.md b/README.md index be58a843..1fa1d30c 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ $ composer require localheinz/json-normalizer This package comes with the following normalizers: +* [`Localheinz\Json\Normalizer\CallableNormalizer`](#callablenormalizer) * [`Localheinz\Json\Normalizer\FinalNewLineNormalizer`](#finalnewlinenormalizer) * [`Localheinz\Json\Normalizer\IndentNormalizer`](#indentnormalizer) * [`Localheinz\Json\Normalizer\JsonEncodeNormalizer`](#jsonencodenormalizer) @@ -26,6 +27,41 @@ This package comes with the following normalizers: :bulb: All of these normalizers implement the `Localheinz\Json\Normalizer\NormalizerInterface`. +### `CallableNormalizer` + +If you want to normalize a JSON file with a `callable`, you can use the `CallableNormalizer`. + +```php +use Localheinz\Json\Normalizer; + +$json = <<<'JSON' +{ + "name": "Andreas Möller", + "url": "https://localheinz.com" +} +JSON; + +$callable = function (string $json): string { + $decoded = json_decode($json); + + foreach (get_object_vars($decoded) as $name => $value) { + if ('https://localheinz.com' !== $value) { + continue; + } + + $decoded->{$name} .= '/open-source/'; + } + + return json_encode($decoded); +}; + +$normalizer = new Normalizer\CallableNormalizer($callable); + +$normalized = $normalizer->normalize($json); +``` + +The normalized version will now have the callable applied to it. + ### `FinalNewLineNormalizer` If you want to ensure that a JSON file has a single final new line, you can use the `FinalNewLineNormalizer`. diff --git a/src/CallableNormalizer.php b/src/CallableNormalizer.php new file mode 100644 index 00000000..fbc41800 --- /dev/null +++ b/src/CallableNormalizer.php @@ -0,0 +1,41 @@ +callable = $callable; + } + + public function normalize(string $json): string + { + if (null === \json_decode($json) && JSON_ERROR_NONE !== \json_last_error()) { + throw new \InvalidArgumentException(\sprintf( + '"%s" is not valid JSON.', + $json + )); + } + + $callable = $this->callable; + + return $callable($json); + } +} diff --git a/test/Unit/CallableNormalizerTest.php b/test/Unit/CallableNormalizerTest.php new file mode 100644 index 00000000..5d835036 --- /dev/null +++ b/test/Unit/CallableNormalizerTest.php @@ -0,0 +1,86 @@ +assertSame($normalized, $normalizer->normalize($json)); + } + + public function providerCallable(): \Generator + { + $values = [ + 'closure' => function (string $json): string { + $decoded = \json_decode($json); + + foreach (\get_object_vars($decoded) as $name => $value) { + if (!\is_int($value)) { + continue; + } + + $decoded->{$name} = $value + 1; + } + + return \json_encode($decoded); + }, + 'function-name' => 'trim', + 'method' => [ + self::class, + 'callable', + ], + ]; + + foreach ($values as $key => $value) { + yield $key => [ + $value, + ]; + } + } + + public static function callable(string $json): string + { + $decoded = \json_decode($json); + + foreach (\get_object_vars($decoded) as $name => $value) { + if (!\is_string($value)) { + continue; + } + + $decoded->{$name} = $value . ' (ok)'; + } + + return \json_encode($decoded); + } +}