Use goccy/go-yaml instead of invopop/yaml?
https://github.com/goccy/go-yaml The library preserves the order of fields when converting from YAML It should fix deepmap/oapi-codegen#458
@renom if I use yaml.Marshal(&base) (goccy) paths are empty.
If I do:
b, err := json.Marshal(&base)
if err != nil {
return fmt.Errorf("marshalling base: %w", err)
}
b, err = yaml.JSONToYAML(b)
if err != nil {
return fmt.Errorf("converting to yaml: %w", err)
}
I get paths but order is lost. Am I using it wrong?
I'm not sure if I understand your question correctly. I'll write what I've found out since I opened the issue.
- To preserve the order of fields, you need to use goccy's type
MapSliceinstead of a regular map: https://github.com/goccy/go-yaml/blob/master/yaml.go#L68
For example:
struct {
Map map[string]string
}
Should become:
struct {
Map yaml.MapSlice
}
-
MapSliceis an ordered version ofmap[any]any. So if you wanna have an equivalent of something likemap[string]intormap[string]struct{}, it isn't supported unless you convert it toMapSlice(an equivalent ofmap[any]any). - I've created an issue that suggests supporting a generic
MapSlice(e.g.MapSlice[string, SpecificMapValue]): https://github.com/goccy/go-yaml/issues/422 Still hasn't got a response though.
I can't use a map, I'm trying to convert an openapi type struct. e.g.
// T is the root of an OpenAPI v3 document
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#openapi-object
type T struct {
Extensions map[string]interface{} `json:"-" yaml:"-"`
OpenAPI string `json:"openapi" yaml:"openapi"` // Required
Components *Components `json:"components,omitempty" yaml:"components,omitempty"`
Info *Info `json:"info" yaml:"info"` // Required
Paths *Paths `json:"paths" yaml:"paths"` // Required
Security SecurityRequirements `json:"security,omitempty" yaml:"security,omitempty"`
Servers Servers `json:"servers,omitempty" yaml:"servers,omitempty"`
Tags Tags `json:"tags,omitempty" yaml:"tags,omitempty"`
ExternalDocs *ExternalDocs `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"`
visited visitedComponent
}
Which has it's own MarshalJSON method, which then I convert to yaml.
I'm thinking generic MapSlice would be a better struct that the one I use in https://github.com/getkin/kin-openapi/pull/695
@renom can you share your experience using MapSlice? What do you think of using this as the go-to map[_]_ within the lib?