Change map and struct marshaling & Fix encoding issues

- Typst dictionaries can use string literals as keys, which is more stable than using identifiers. This also means we don't have to use CleanIdentifier.
- Add more tests for corner cases.
This commit is contained in:
David Vogel 2024-12-19 18:07:44 +01:00
parent bff3077b6d
commit 7b0454ae68
2 changed files with 15 additions and 5 deletions

View File

@ -246,7 +246,10 @@ func (e *VariableEncoder) encodeStruct(v reflect.Value, t reflect.Type) error {
return err
}
// TODO: Allow name customization via struct tags
if err := e.writeString(CleanIdentifier(ft.Name) + ": "); err != nil {
if err := e.writeStringLiteral([]byte(ft.Name)); err != nil {
return err
}
if err := e.writeString(": "); err != nil {
return err
}
if err := e.marshal(fv); err != nil {
@ -313,7 +316,7 @@ func (e *VariableEncoder) encodeMap(v reflect.Value) error {
if err != nil {
return err
}
pairs = append(pairs, pair{CleanIdentifier(key), mv})
pairs = append(pairs, pair{key, mv})
}
// Sort and then generate markup.
@ -324,7 +327,10 @@ func (e *VariableEncoder) encodeMap(v reflect.Value) error {
if err := e.writeIndentationCharacters(); err != nil {
return err
}
if err := e.writeString(key + ": "); err != nil {
if err := e.writeStringLiteral([]byte(key)); err != nil {
return err
}
if err := e.writeString(": "); err != nil {
return err
}
if err := e.marshal(value); err != nil {

View File

@ -125,12 +125,16 @@ func TestVariableEncoder(t *testing.T) {
{"struct", struct {
Foo string
Bar int
}{"Hey!", 12345}, false, "(\n Foo: \"Hey!\",\n Bar: 12345,\n)"},
}{"Hey!", 12345}, false, "(\n \"Foo\": \"Hey!\",\n \"Bar\": 12345,\n)"},
{"struct empty", struct{}{}, false, "()"},
{"struct empty pointer", (*struct{})(nil), false, "none"},
{"map string string", map[string]string{"Foo": "Bar", "Foo2": "Electric Foogaloo"}, false, "(\n Foo: \"Bar\",\n Foo2: \"Electric Foogaloo\",\n)"},
{"map string string", map[string]string{"Foo": "Bar", "Foo2": "Electric Foogaloo"}, false, "(\n \"Foo\": \"Bar\",\n \"Foo2\": \"Electric Foogaloo\",\n)"},
{"map string string empty", map[string]string{}, false, "()"},
{"map string string nil", map[string]string(nil), false, "()"},
{"map string string key escape", map[string]string{"A\nNew": "Line"}, false, "(\n \"A\\nNew\": \"Line\",\n)"},
{"map int string", map[int]string{1: "Foo", 2: "Bar"}, false, "(\n \"1\": \"Foo\",\n \"2\": \"Bar\",\n)"},
{"map int string negative keys", map[int]string{-1: "Foo", -2: "Bar"}, false, "(\n \"-1\": \"Foo\",\n \"-2\": \"Bar\",\n)"},
{"map uint string", map[uint]string{1: "Foo", 2: "Bar"}, false, "(\n \"1\": \"Foo\",\n \"2\": \"Bar\",\n)"},
{"string array", [5]string{"Foo", "Bar"}, false, `("Foo", "Bar", "", "", "")`},
{"string array 1", [1]string{"Foo"}, false, `("Foo",)`},
{"string slice", []string{"Foo", "Bar"}, false, `("Foo", "Bar")`},