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

gapic: untangle Iterator logic with generics #1305

Open
noahdietz opened this issue Apr 18, 2023 · 0 comments
Open

gapic: untangle Iterator logic with generics #1305

noahdietz opened this issue Apr 18, 2023 · 0 comments
Labels
type: feature request ‘Nice-to-have’ improvement, new feature or different behavior or design.

Comments

@noahdietz
Copy link
Collaborator

This requires Go 1.18+ be the minimum supported version for clients.

The Iterator interface has worked great but the generated code in GAPICs for it is kind of messy and confusing. With generics, we could create explore more general implementations that were more streamlined. For example (copied from internal link):

// Playing with https://github.com/golang/go/discussions/54245
// -----------------------------------------------------------------------------
// in standard library
type Iter2[E1, E2 any] interface {
	Next() (E1, E2, bool)
}
 
// -----------------------------------------------------------------------------
// in client library
// existing
 
type Secret struct{}
type SecretIterator struct{}
func (it *SecretIterator) Next() (*Secret, error) { return nil, nil }
 
// New
func (it *SecretIterator) Range() Iter2[*Secret, error] {
	return NewStdIter[*Secret](it)
}
 
// -----------------------------------------------------------------------------
// in iterator package
// existing
 
var Done = fmt.Errorf("done")
 
// New
 
// Nexter is an interface all client library iterators implement.
type Nexter[T any] interface {
	Next() (T, error)
}
 
func NewStdIter[T any](from Nexter[T]) Iter2[T, error] {
	return stdIteratorAdapter[T]{from}
}
 
type stdIteratorAdapter[T any] struct {
	n Nexter[T]
}
 
func (n stdIteratorAdapter[T]) Next() (T, error, bool) {
	r, err := n.n.Next()
	if err == Done {
		var zero T
		return zero, nil, false
	}
	return r, err, err == nil
}
 
// -----------------------------------------------------------------------------
// Old usage
 
it := c.ListSecrets(ctx, req)
for {
	resp, err := it.Next()
	if err == iterator.Done {
		break
	}
	if err != nil {
		// TODO: Handle error.
	}
	// TODO: Use resp.
	_ = resp
}
 
// New usage
for resp, err := range c.ListSecrets(ctx, req) {
	if err != nil {
		// TODO: Handle error.
	}
	// TODO: Use resp.
	_ = resp
}
@noahdietz noahdietz added the type: feature request ‘Nice-to-have’ improvement, new feature or different behavior or design. label Apr 18, 2023
@noahdietz noahdietz added this to the Go GAPIC Modernization milestone Apr 18, 2023
@quartzmo quartzmo removed this from the Go GAPIC Modernization milestone Feb 16, 2024
@noahdietz noahdietz added this to the Go GAPIC Modernization milestone Feb 28, 2024
@quartzmo quartzmo removed this from the Go GAPIC Modernization milestone Feb 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: feature request ‘Nice-to-have’ improvement, new feature or different behavior or design.
Projects
None yet
Development

No branches or pull requests

2 participants