Skip to content

Commit

Permalink
feat(option/internaloption): add new EmbeddableAdapter option (#1787)
Browse files Browse the repository at this point in the history
  • Loading branch information
codyoss committed Dec 15, 2022
1 parent a7f08e2 commit 1569e5b
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 0 deletions.
1 change: 1 addition & 0 deletions internal/kokoro/vet.sh
Expand Up @@ -37,6 +37,7 @@ golint ./... 2>&1 | ( \
grep -v "exported method MarshalStyle.JSONReader should have comment or be unexported" | \
grep -v "UnmarshalJSON should have comment or be unexported" | \
grep -v "MarshalJSON should have comment or be unexported" | \
grep -v ".Apply should have comment or be unexported" | \
grep -vE "\.pb\.go:" || true) | tee /dev/stderr | (! read)

staticcheck -go 1.9 ./... 2>&1 | ( \
Expand Down
7 changes: 7 additions & 0 deletions option/internaloption/internaloption.go
Expand Up @@ -134,3 +134,10 @@ type withCreds google.Credentials
func (w *withCreds) Apply(o *internal.DialSettings) {
o.InternalCredentials = (*google.Credentials)(w)
}

// EmbeddableAdapter is a no-op option.ClientOption that allow libraries to
// create their own client options by embedding this type into their own
// client-specific option wrapper. See example for usage.
type EmbeddableAdapter struct{}

func (*EmbeddableAdapter) Apply(_ *internal.DialSettings) {}
62 changes: 62 additions & 0 deletions option/internaloption/internaloption_external_test.go
@@ -0,0 +1,62 @@
// Copyright 2022 Google LLC.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package internaloption_test

import (
"context"
"fmt"

"google.golang.org/api/option"
"google.golang.org/api/option/internaloption"
)

type config struct {
i int
}

type clientSpecificOption interface {
option.ClientOption
ApplyOpt(*config)
}

func WithFavoriteNumber(i int) option.ClientOption {
return &withFavoriteNumber{i: i}
}

type withFavoriteNumber struct {
internaloption.EmbeddableAdapter
i int
}

func (w *withFavoriteNumber) ApplyOpt(c *config) {
c.i = w.i
}

type Foo struct {
i int
}

func NewFoo(ctx context.Context, opts ...option.ClientOption) (*Foo, error) {
var conf config
for _, opt := range opts {
if fooOpt, ok := opt.(clientSpecificOption); ok {
fooOpt.ApplyOpt(&conf)
}
}
// Pass options to internals for dialing. All client-specific options will
// be no-ops.
return &Foo{i: conf.i}, nil
}

func (f *Foo) Number() int { return f.i }

func ExampleEmbeddableAdapter() {
f, err := NewFoo(context.Background(), WithFavoriteNumber(42))
if err != nil {
// TODO: handle error
}
fmt.Println(f.Number())
// Output: 42
}

0 comments on commit 1569e5b

Please sign in to comment.