Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use goccy/go-yaml instead of invopop/yaml? #849

Open
renom opened this issue Oct 19, 2023 · 4 comments
Open

Use goccy/go-yaml instead of invopop/yaml? #849

renom opened this issue Oct 19, 2023 · 4 comments

Comments

@renom
Copy link

renom commented Oct 19, 2023

https://github.com/goccy/go-yaml
The library preserves the order of fields when converting from YAML
It should fix oapi-codegen/oapi-codegen#458

@sonu27
Copy link
Contributor

sonu27 commented Feb 5, 2024

@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?

@renom
Copy link
Author

renom commented Feb 5, 2024

I'm not sure if I understand your question correctly. I'll write what I've found out since I opened the issue.

  1. To preserve the order of fields, you need to use goccy's type MapSlice instead 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
}
  1. MapSlice is an ordered version of map[any]any. So if you wanna have an equivalent of something like map[string]int or map[string]struct{}, it isn't supported unless you convert it to MapSlice (an equivalent of map[any]any).
  2. I've created an issue that suggests supporting a generic MapSlice (e.g. MapSlice[string, SpecificMapValue]):
    Support generic map slice goccy/go-yaml#422
    Still hasn't got a response though.

@sonu27
Copy link
Contributor

sonu27 commented Feb 6, 2024

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.

@fenollp
Copy link
Collaborator

fenollp commented Mar 22, 2024

I'm thinking generic MapSlice would be a better struct that the one I use in #695

@renom can you share your experience using MapSlice? What do you think of using this as the go-to map[_]_ within the lib?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants