Skip to content

Commit 9d49876

Browse files
alamiraultderrabus
authored andcommitted
[Yaml] Add flag to dump numeric key as string
1 parent 9461dec commit 9d49876

File tree

6 files changed

+196
-0
lines changed

6 files changed

+196
-0
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
6.3
5+
---
6+
7+
* Add support to dump int keys as strings by using the `Yaml::DUMP_NUMERIC_KEY_AS_STRING` flag.
8+
49
6.2
510
---
611

Dumper.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ public function dump(mixed $input, int $inline = 0, int $indent = 0, int $flags
6464
$output .= "\n";
6565
}
6666

67+
if (\is_int($key) && Yaml::DUMP_NUMERIC_KEY_AS_STRING & $flags) {
68+
$key = (string) $key;
69+
}
70+
6771
if (Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value) && str_contains($value, "\n") && !str_contains($value, "\r")) {
6872
// If the first line starts with a space character, the spec requires a blockIndicationIndicator
6973
// http://www.yaml.org/spec/1.2/spec.html#id2793979

Inline.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,10 @@ private static function dumpHashArray(array|\ArrayObject|\stdClass $value, int $
239239
{
240240
$output = [];
241241
foreach ($value as $key => $val) {
242+
if (\is_int($key) && Yaml::DUMP_NUMERIC_KEY_AS_STRING & $flags) {
243+
$key = (string) $key;
244+
}
245+
242246
$output[] = sprintf('%s: %s', self::dump($key, $flags), self::dump($val, $flags));
243247
}
244248

Tests/DumperTest.php

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,96 @@ public function testDumpNullAsTilde()
804804
$this->assertSame('{ foo: ~ }', $this->dumper->dump(['foo' => null], 0, 0, Yaml::DUMP_NULL_AS_TILDE));
805805
}
806806

807+
/**
808+
* @dataProvider getNumericKeyData
809+
*/
810+
public function testDumpInlineNumericKeyAsString(array $input, bool $inline, int $flags, string $expected)
811+
{
812+
$this->assertSame($expected, $this->dumper->dump($input, $inline ? 0 : 4, 0, $flags));
813+
}
814+
815+
public function getNumericKeyData()
816+
{
817+
yield 'Int key with flag inline' => [
818+
[200 => 'foo'],
819+
true,
820+
Yaml::DUMP_NUMERIC_KEY_AS_STRING,
821+
"{ '200': foo }",
822+
];
823+
824+
yield 'Int key without flag inline' => [
825+
[200 => 'foo'],
826+
true,
827+
0,
828+
'{ 200: foo }',
829+
];
830+
831+
$expected = <<<'YAML'
832+
'200': foo
833+
834+
YAML;
835+
836+
yield 'Int key with flag' => [
837+
[200 => 'foo'],
838+
false,
839+
Yaml::DUMP_NUMERIC_KEY_AS_STRING,
840+
$expected,
841+
];
842+
843+
$expected = <<<'YAML'
844+
200: foo
845+
846+
YAML;
847+
848+
yield 'Int key without flag' => [
849+
[200 => 'foo'],
850+
false,
851+
0,
852+
$expected,
853+
];
854+
855+
$expected = <<<'YAML'
856+
- 200
857+
- foo
858+
859+
YAML;
860+
861+
yield 'List array with flag' => [
862+
[200, 'foo'],
863+
false,
864+
Yaml::DUMP_NUMERIC_KEY_AS_STRING,
865+
$expected,
866+
];
867+
868+
$expected = <<<'YAML'
869+
'200': !number 5
870+
871+
YAML;
872+
873+
yield 'Int tagged value with flag' => [
874+
[
875+
200 => new TaggedValue('number', 5),
876+
],
877+
false,
878+
Yaml::DUMP_NUMERIC_KEY_AS_STRING,
879+
$expected,
880+
];
881+
882+
$expected = <<<'YAML'
883+
200: !number 5
884+
885+
YAML;
886+
887+
yield 'Int tagged value without flag' => [
888+
[
889+
200 => new TaggedValue('number', 5),
890+
],
891+
false,
892+
0,
893+
$expected,
894+
];
895+
}
896+
807897
public function testDumpIdeographicSpaces()
808898
{
809899
$expected = <<<YAML

Tests/InlineTest.php

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,98 @@ public function testDumpDateTime($dateTime, $expected)
617617
$this->assertSame($expected, Inline::dump($dateTime));
618618
}
619619

620+
/**
621+
* @dataProvider getNumericKeyData
622+
*/
623+
public function testDumpNumericKeyAsString(array|int $input, int $flags, string $expected)
624+
{
625+
$this->assertSame($expected, Inline::dump($input, $flags));
626+
}
627+
628+
public function getNumericKeyData()
629+
{
630+
yield 'Int with flag' => [
631+
200,
632+
Yaml::DUMP_NUMERIC_KEY_AS_STRING,
633+
'200',
634+
];
635+
636+
yield 'Int key with flag' => [
637+
[200 => 'foo'],
638+
Yaml::DUMP_NUMERIC_KEY_AS_STRING,
639+
"{ '200': foo }",
640+
];
641+
642+
yield 'Int value with flag' => [
643+
[200 => 200],
644+
Yaml::DUMP_NUMERIC_KEY_AS_STRING,
645+
"{ '200': 200 }",
646+
];
647+
648+
yield 'String key with flag' => [
649+
['200' => 'foo'],
650+
Yaml::DUMP_NUMERIC_KEY_AS_STRING,
651+
"{ '200': foo }",
652+
];
653+
654+
yield 'Mixed with flag' => [
655+
[42 => 'a', 'b' => 'c', 'd' => 43],
656+
Yaml::DUMP_NUMERIC_KEY_AS_STRING,
657+
"{ '42': a, b: c, d: 43 }",
658+
];
659+
660+
yield 'Auto-index with flag' => [
661+
['a', 'b', 42],
662+
Yaml::DUMP_NUMERIC_KEY_AS_STRING,
663+
'[a, b, 42]',
664+
];
665+
666+
yield 'Complex mixed array with flag' => [
667+
[
668+
42 => [
669+
'foo' => 43,
670+
44 => 'bar',
671+
],
672+
45 => 'baz',
673+
46,
674+
],
675+
Yaml::DUMP_NUMERIC_KEY_AS_STRING,
676+
"{ '42': { foo: 43, '44': bar }, '45': baz, '46': 46 }",
677+
];
678+
679+
yield 'Int tagged value with flag' => [
680+
[
681+
'count' => new TaggedValue('number', 5),
682+
],
683+
Yaml::DUMP_NUMERIC_KEY_AS_STRING,
684+
'{ count: !number 5 }',
685+
];
686+
687+
yield 'Array tagged value with flag' => [
688+
[
689+
'user' => new TaggedValue('metadata', [
690+
'john',
691+
42,
692+
]),
693+
],
694+
Yaml::DUMP_NUMERIC_KEY_AS_STRING,
695+
'{ user: !metadata [john, 42] }',
696+
];
697+
698+
$arrayObject = new \ArrayObject();
699+
$arrayObject['foo'] = 'bar';
700+
$arrayObject[42] = 'baz';
701+
$arrayObject['baz'] = 43;
702+
703+
yield 'Object value with flag' => [
704+
[
705+
'user' => $arrayObject,
706+
],
707+
Yaml::DUMP_NUMERIC_KEY_AS_STRING | Yaml::DUMP_OBJECT_AS_MAP,
708+
"{ user: { foo: bar, '42': baz, baz: 43 } }",
709+
];
710+
}
711+
620712
public function testDumpUnitEnum()
621713
{
622714
$this->assertSame("!php/const Symfony\Component\Yaml\Tests\Fixtures\FooUnitEnum::BAR", Inline::dump(FooUnitEnum::BAR));

Yaml.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class Yaml
3434
public const PARSE_CUSTOM_TAGS = 512;
3535
public const DUMP_EMPTY_ARRAY_AS_SEQUENCE = 1024;
3636
public const DUMP_NULL_AS_TILDE = 2048;
37+
public const DUMP_NUMERIC_KEY_AS_STRING = 4096;
3738

3839
/**
3940
* Parses a YAML file into a PHP value.

0 commit comments

Comments
 (0)