diff --git a/properties.go b/properties.go index 4142308..c498818 100644 --- a/properties.go +++ b/properties.go @@ -25,21 +25,26 @@ type OrderSchemaItems []OrderSchemaItem // of the OrderSchemaItems slice, keeping the original order of the slice. func (items OrderSchemaItems) MarshalJSON() ([]byte, error) { buf := bytes.NewBuffer(nil) - buf.WriteString("{") - for i := range items { - if i > 0 { - buf.WriteString(",") - } - buf.WriteString("\"") - buf.WriteString(items[i].Name) - buf.WriteString("\":") - bs, err := json.Marshal(&items[i].Schema) - if err != nil { + buf.WriteByte('{') + + if len(items) == 0 { + buf.WriteByte('}') + + return buf.Bytes(), nil + } + + if err := items.marshalJSONItem(items[0], buf); err != nil { + return nil, err + } + + for _, item := range items[1:] { + buf.WriteByte(',') + if err := items.marshalJSONItem(item, buf); err != nil { return nil, err } - buf.Write(bs) } - buf.WriteString("}") + buf.WriteByte('}') + return buf.Bytes(), nil } @@ -69,6 +74,22 @@ func (items OrderSchemaItems) Less(i, j int) (ret bool) { return items[i].Name < items[j].Name } +func (items OrderSchemaItems) marshalJSONItem(item OrderSchemaItem, output *bytes.Buffer) error { + nameJSON, err := json.Marshal(item.Name) + if err != nil { + return err + } + output.Write(nameJSON) + output.WriteByte(':') + schemaJSON, err := json.Marshal(&item.Schema) + if err != nil { + return err + } + output.Write(schemaJSON) + + return nil +} + // SchemaProperties is a map representing the properties of a Schema object. // It knows how to transform its keys into an ordered slice. type SchemaProperties map[string]Schema diff --git a/properties_test.go b/properties_test.go index 2874a0d..8475dfe 100644 --- a/properties_test.go +++ b/properties_test.go @@ -5,6 +5,8 @@ package spec import ( "testing" + + "github.com/go-openapi/testify/v2/require" ) func TestPropertySerialization(t *testing.T) { @@ -45,3 +47,25 @@ func TestPropertySerialization(t *testing.T) { } } + +func TestOrderedSchemaItem_Issue216(t *testing.T) { + stringSchema := new(Schema).Typed("string", "") + items := OrderSchemaItems{ + { + Name: "emails\n", // Key contains newline character + Schema: *stringSchema, + }, + { + Name: "regular", + Schema: *stringSchema, + }, + } + + jazon, err := items.MarshalJSON() + require.NoError(t, err) + + require.JSONEqBytes(t, + []byte(`{"emails\n":{"type":"string"},"regular":{"type":"string"}}`), + jazon, + ) +}