.. _json5_objects: Helper Objects ############## .. highlight:: php The helper objects allow you control how specific values are rendered. They are also designed to be JSON-transparent so you can get an equivalent JSON file by using ``json_encode()``. This compatibility may be broken by some planned objects. Scalar Decorators ================= ``HexInteger`` -------------- .. versionadded:: 1.1 ``$padding`` Renders an integer in a hexadecimal form:: new HexInteger(0xdeadbeef), 'hex2' => new HexInteger(0xbeef), 'hex3' => new HexInteger(0xbeef, 8), // optional padding ]; echo Json5Encoder::encode($value); echo JsonCEncoder::encode($value); echo JsonEncoder::encode($value); echo json_encode($value, JSON_PRETTY_PRINT); .. tabs:: .. code-tab:: json5 JSON5 { hex1: 0xDEADBEEF, hex2: 0xBEEF, hex3: 0x0000BEEF, } .. code-tab:: json JSONC { "hex1": 3735928559, "hex2": 48879, "hex3": 48879 } .. code-tab:: json JSON (JsonEncoder) { "hex1": 3735928559, "hex2": 48879, "hex3": 48879 } .. code-tab:: json JSON (json_encode) { "hex1": 3735928559, "hex2": 48879, "hex3": 48879 } Container Decorators ==================== For arrays and objects. ``ArrayValue`` and ``ObjectValue`` ---------------------------------- .. versionadded:: 1.1 ``\Arokettu\Json5\Values\ArrayValue`` ``\Arokettu\Json5\Values\ObjectValue`` These two decorators wrap any ``iterable`` or ``stdClass`` to be forced to render as either a array or an object:: yield from range(0, 3)); $value = [ 'array' => new ArrayValue([1 => 2, 3 => 4]), // no need for consecutive keys 'object' => new ObjectValue([1, 2, 3, 4]), // list becomes object 'iterable' => new ArrayValue($generator()), // try a generator ]; echo Json5Encoder::encode($value); $value['iterable'] = new ArrayValue($generator()); // can't traverse a generator twice echo JsonCEncoder::encode($value); $value['iterable'] = new ArrayValue($generator()); // can't traverse a generator twice echo JsonEncoder::encode($value); $value['iterable'] = new ArrayValue($generator()); // can't traverse a generator twice echo json_encode($value, JSON_PRETTY_PRINT); .. tabs:: .. code-tab:: json5 JSON5 { array: [ 2, 4, ], object: { '0': 1, '1': 2, '2': 3, '3': 4, }, iterable: [ 0, 1, 2, 3, ], } .. code-tab:: json JSONC { "array": [ 2, 4 ], "object": { "0": 1, "1": 2, "2": 3, "3": 4 }, "iterable": [ 0, 1, 2, 3 ] } .. code-tab:: json JSON (JsonEncoder) { "array": [ 2, 4 ], "object": { "0": 1, "1": 2, "2": 3, "3": 4 }, "iterable": [ 0, 1, 2, 3 ] } .. code-tab:: json JSON (json_encode) { "array": [ 2, 4 ], "object": { "0": 1, "1": 2, "2": 3, "3": 4 }, "iterable": [ 0, 1, 2, 3 ] } .. note:: If an iterable wrapped by an instance of ``ObjectValue`` (and similar object wrappers) has duplicate keys, your JSON5 file will have duplicate keys too. ``InlineArray`` and ``InlineObject`` ------------------------------------ ``\Arokettu\Json5\Values\InlineArray`` ``\Arokettu\Json5\Values\InlineObject`` These wrappers act similar to ``ArrayValue`` and ``ObjectValue`` but intended for small arrays and objects that can be written in a single line:: new InlineArray([1, 2, 3, 4]), 'tinyObject' => new InlineObject(['key' => 'value']), ]; echo Json5Encoder::encode($value); echo JsonCEncoder::encode($value); echo JsonEncoder::encode($value); echo json_encode($value, JSON_PRETTY_PRINT); .. tabs:: .. code-tab:: json5 JSON5 // Compact and nice { tinyArray: [1, 2, 3, 4], tinyObject: { key: "value" }, } .. code-tab:: json JSONC // Compact and nice too { "tinyArray": [1, 2, 3, 4], "tinyObject": { "key": "value" } } .. code-tab:: json JSON (JsonEncoder) // Compact and nice too { "tinyArray": [1, 2, 3, 4], "tinyObject": { "key": "value" } } .. code-tab:: json JSON (json_encode) // Quite wasteful { "tinyArray": [ 1, 2, 3, 4 ], "tinyObject": { "key": "value" } } Nesting container structures is also fine:: new InlineArray([ ['name' => 'Andy Gutmans', 'email' => 'example@example.com', 'role' => 'co-founder'], ['name' => 'Zeev Suraski', 'email' => 'example@example.com', 'role' => 'co-founder'], ]), 'repositories' => [ new InlineObject(['type' => 'vcs', 'url' => 'http://localhost/php.git']), new InlineObject(['type' => 'vcs', 'url' => 'http://localhost/zend.git']), ], ]; echo Json5Encoder::encode($value); echo JsonCEncoder::encode($value); echo JsonEncoder::encode($value); echo json_encode($value, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); .. tabs:: .. code-tab:: json5 JSON5 { authors: [{ name: "Andy Gutmans", email: "example@example.com", role: "co-founder", }, { name: "Zeev Suraski", email: "example@example.com", role: "co-founder", }], repositories: [ { type: "vcs", url: "http://localhost/php.git" }, { type: "vcs", url: "http://localhost/zend.git" }, ], } .. code-tab:: json JSONC { "authors": [{ "name": "Andy Gutmans", "email": "example@example.com", "role": "co-founder" }, { "name": "Zeev Suraski", "email": "example@example.com", "role": "co-founder" }], "repositories": [ { "type": "vcs", "url": "http://localhost/php.git" }, { "type": "vcs", "url": "http://localhost/zend.git" } ] } .. code-tab:: json JSON (JsonEncoder) { "authors": [{ "name": "Andy Gutmans", "email": "example@example.com", "role": "co-founder" }, { "name": "Zeev Suraski", "email": "example@example.com", "role": "co-founder" }], "repositories": [ { "type": "vcs", "url": "http://localhost/php.git" }, { "type": "vcs", "url": "http://localhost/zend.git" } ] } .. code-tab:: json JSON (json_encode) { "authors": [ { "name": "Andy Gutmans", "email": "example@example.com", "role": "co-founder" }, { "name": "Zeev Suraski", "email": "example@example.com", "role": "co-founder" } ], "repositories": [ { "type": "vcs", "url": "http://localhost/php.git" }, { "type": "vcs", "url": "http://localhost/zend.git" } ] } ``CompactArray`` and ``CompactObject`` -------------------------------------- ``\Arokettu\Json5\Values\CompactArray`` ``\Arokettu\Json5\Values\CompactObject`` A middle ground between normal and inline structures best used with a manual newline using :ref:`json5_objects_eol`, also notice various comment types behavior:: new CompactArray([1, 2, new EndOfLine(), 3, 4]), 'tinyObject' => new CompactObject(['key1' => 'value1', 'key2' => 'value2']), 'comments' => new CompactArray([ new Comment('Standalone comment is a line comment'), new CommentDecorator('become', 'Decorator comments', 'inline comments'), ]), ]; echo Json5Encoder::encode($value); echo JsonCEncoder::encode($value); echo JsonEncoder::encode($value); echo json_encode($value, JSON_PRETTY_PRINT); .. tabs:: .. code-tab:: json5 JSON5 { tinyArray: [ 1, 2, 3, 4, ], tinyObject: { key1: "value1", key2: "value2", }, comments: [ // Standalone comment is a line comment /* Decorator comments */ "become" /* inline comments */, ], } .. code-tab:: json JSONC { "tinyArray": [ 1, 2, 3, 4 ], "tinyObject": { "key1": "value1", "key2": "value2" }, "comments": [ // Standalone comment is a line comment /* Decorator comments */ "become" /* inline comments */ ] } .. code-tab:: json JSON (JsonEncoder) { "tinyArray": [ 1, 2, 3, 4 ], "tinyObject": { "key1": "value1", "key2": "value2" }, "comments": [ "become" ] } .. code-tab:: json JSON (json_encode) { "tinyArray": [ 1, 2, {}, 3, 4 ], "tinyObject": { "key1": "value1", "key2": "value2" }, "comments": [ { "comment": "Standalone comment is a line comment" }, "become" ] } Common Decorators ================= ``CommentDecorator`` -------------------- Renders a value with comments. The ``commentBefore`` may be multiline, the ``commentAfter`` must be a single line:: new CommentDecorator(6.6743e-11, commentBefore: << [new Comment('Normal mode'), 'value1', 'value2', 'value3'], 'compact' => new CompactArray([ new Comment('Unlike decorator, standalone comment is rendered on its own line here'), 'value1', 'value2', new Comment('JsonEncoder will leave EOL here'), 'value3', ]), 'inline' => new InlineArray([new Comment('Inline mode'), 'value1', 'value2', 'value3']), ]; echo Json5Encoder::encode($value); echo JsonCEncoder::encode($value); echo JsonEncoder::encode($value); echo json_encode($value, JSON_PRETTY_PRINT); .. tabs:: .. code-tab:: json5 JSON5 { normal: [ // Normal mode "value1", "value2", "value3", ], compact: [ // Unlike decorator, standalone comment is rendered on its own line here "value1", "value2", // JsonEncoder will leave EOL here "value3", ], inline: [/* Inline mode */ "value1", "value2", "value3"], } .. code-tab:: json JSONC { "normal": [ // Normal mode "value1", "value2", "value3" ], "compact": [ // Unlike decorator, standalone comment is rendered on its own line here "value1", "value2", // JsonEncoder will leave EOL here "value3" ], "inline": [/* Inline mode */ "value1", "value2", "value3"] } .. code-tab:: json JSON (JsonEncoder) { "normal": [ "value1", "value2", "value3" ], "compact": [ "value1", "value2", "value3" ], "inline": ["value1", "value2", "value3"] } .. code-tab:: json JSON (json_encode) { "normal": [ { "comment": "Normal mode" }, "value1", "value2", "value3" ], "compact": [ { "comment": "Unlike decorator, standalone comment is rendered on its own line here" }, "value1", "value2", { "comment": "JsonEncoder will leave EOL here" }, "value3" ], "inline": [ { "comment": "Inline mode" }, "value1", "value2", "value3" ] } .. _json5_objects_eol: ``EndOfLine`` ------------- ``\Arokettu\Json5\Values\EndOfLine`` Inserts a newline character:: [1, 2, new EndOfLine(), 3, 4], 'inline' => new InlineArray([1, 2, new EndOfLine(), 3, 4]), 'compact' => new CompactArray([1, 2, new EndOfLine(), 3, 4]), ]; echo Json5Encoder::encode($value); echo JsonCEncoder::encode($value); echo JsonEncoder::encode($value); echo json_encode($value, JSON_PRETTY_PRINT); .. tabs:: .. code-tab:: json5 JSON5 { regular: [ 1, 2, 3, 4, ], inline: [1, 2, 3, 4], compact: [ 1, 2, 3, 4, ], } .. code-tab:: json JSONC { "regular": [ 1, 2, 3, 4 ], "inline": [1, 2, 3, 4], "compact": [ 1, 2, 3, 4 ] } .. code-tab:: json JSON (JsonEncoder) { "regular": [ 1, 2, 3, 4 ], "inline": [1, 2, 3, 4], "compact": [ 1, 2, 3, 4 ] } .. code-tab:: json JSON (json_encode) { "regular": [ 1, 2, {}, // not transparent 3, 4 ], "inline": [ 1, 2, {}, // not transparent 3, 4 ], "compact": [ 1, 2, {}, // not transparent 3, 4 ] }