libopenapi icon indicating copy to clipboard operation
libopenapi copied to clipboard

Slowly migrate to range over func

Open petkostas opened this issue 1 year ago • 5 comments

I have been struggling to find a good and clean solution for the introduced ordered map structs. Maybe consider and support the range-over-func experiment? It would remove the burden of having to re-create iterators for iterating over elements that are not natively supported by GO libraries 😄 I know it is still experimental, but I hardly find any reasons that this will not become stable in the long term.

petkostas avatar Jul 31 '24 19:07 petkostas

The ordered maps have a custom API, it's not ideal, but it means that we can swap out the underlying implementation underneath.

I don't think this is bad at all personally:

for schemaPairs := model.Model.Components.Schemas.First(); schemaPairs != nil; schemaPairs = schemaPairs.Next() {
  // get the name of the schema
  schemaName := schemaPairs.Key()

  // get the schema object from the map
  schemaValue := schemaPairs.Value()

  // build the schema
  schema := schemaValue.Schema()

  // if the schema has properties, print the number of properties
  if schema != nil && schema.Properties != nil {
    fmt.Printf("Schema '%s' has %d properties\n", schemaName, schema.Properties.Len())
  }
}

However, if someone is open to trying to implement this, I think it would be great.

daveshanley avatar Jul 31 '24 20:07 daveshanley

It is not bad! And the implementation is spot on! That is why I love your tools; I was considering that maybe it is a good alternative for the future that better integrates with libraries (e.g., templates). Thanks for always being responsive @daveshanley

petkostas avatar Jul 31 '24 20:07 petkostas

So, I gave it a quick spin today! It works like a charm.

func GetPaths(model *v3.Document) func(yield func(string, *v3.PathItem) bool) {
	iter := func(yield func(string, *v3.PathItem) bool) {
		for path := model.Paths.PathItems.First(); path != nil; path = path.Next() {
			if oas.IsExcluded(path.Value().Extensions) {
				continue
			}
			if !yield(path.Key(), path.Value()) {
				return
			}
		}
	}
	return iter
}

petkostas avatar Aug 04 '24 14:08 petkostas

So, I gave it a quick spin today! It works like a charm.

func GetPaths(model *v3.Document) func(yield func(string, *v3.PathItem) bool) {
	iter := func(yield func(string, *v3.PathItem) bool) {
		for path := model.Paths.PathItems.First(); path != nil; path = path.Next() {
			if oas.IsExcluded(path.Value().Extensions) {
				continue
			}
			if !yield(path.Key(), path.Value()) {
				return
			}
		}
	}
	return iter
}

Nice! this looks great.

What is this though? oas.IsExcluded ?

daveshanley avatar Aug 04 '24 14:08 daveshanley

Ah I iterate over the elements and I check if they need to be excluded for my purpose (e.g. x-internal) You can ignore that, as I modified this method for the example and forgot to remove that part.

petkostas avatar Aug 04 '24 14:08 petkostas

This has been addressed in #319

Courtesy of @TristanSpeakEasy

daveshanley avatar Aug 15 '24 16:08 daveshanley

Available in v0.17

daveshanley avatar Aug 26 '24 19:08 daveshanley