func (b *bucketDelegate) Object(name string) ObjectHandleWrapper {
	return &objectDelegate{object: b.bucket.Object(name)}
}
Object returns an ObjectHandle, which provides operations on the named object.
This call does not perform any network operations.

name must consist entirely of valid UTF-8-encoded runes. The full specification
for valid object names can be found at:
https://cloud.google.com/storage/docs/bucket-naming
package connector
import (
	"context"
	"os"
	"cloud.google.com/go/storage"
	"golang.org/x/oauth2/google"
	"google.golang.org/api/option"
)
type (
	GcloudStorageClient interface {
		Bucket(URI string) BucketHandleWrapper
	}
	clientDelegate struct {
		nativeClient *storage.Client
	}
)
type (
	BucketHandleWrapper interface {
		Object(name string) ObjectHandleWrapper
		Objects(ctx context.Context, q *storage.Query) ObjectIteratorWrapper
		Attrs(ctx context.Context) (*storage.BucketAttrs, error)
	}
	bucketDelegate struct {
		bucket *storage.BucketHandle
	}
)
type (
	ObjectHandleWrapper interface {
		NewWriter(ctx context.Context) WriterWrapper
		NewReader(ctx context.Context) (ReaderWrapper, error)
		Attrs(ctx context.Context) (*storage.ObjectAttrs, error)
	}
	objectDelegate struct {
		object *storage.ObjectHandle
	}
)
type (
	WriterWrapper interface {
		Close() error
		Write(p []byte) (n int, err error)
		CloseWithError(err error) error
	}
	writerDelegate struct {
		writer *storage.Writer
	}
)
type (
	ReaderWrapper interface {
		Close() error
		Read(p []byte) (int, error)
	}
	readerDelegate struct {
		reader *storage.Reader
	}
)
type (
	ObjectIteratorWrapper interface {
		Next() (*storage.ObjectAttrs, error)
	}
	objectIteratorDelegate struct {
		iterator *storage.ObjectIterator
	}
)
func newClientDelegate() (*clientDelegate, error) {
	ctx := context.Background()
	if credentialsPath := os.Getenv("GOOGLE_APPLICATION_CREDENTIALS"); credentialsPath != "" {
		return newClientDelegateWithCredentials(ctx, credentialsPath)
	}
	return newDefaultClientDelegate(ctx)
}
func newDefaultClientDelegate(ctx context.Context) (*clientDelegate, error) {
	nativeClient, err := storage.NewClient(ctx)
	return &clientDelegate{nativeClient: nativeClient}, err
}
func newClientDelegateWithCredentials(ctx context.Context, credentialsPath string) (*clientDelegate, error) {
	jsonKey, err := os.ReadFile(credentialsPath)
	if err != nil {
		return newDefaultClientDelegate(ctx)
	}
	conf, err := google.JWTConfigFromJSON(jsonKey, storage.ScopeFullControl)
	if err != nil {
		return newDefaultClientDelegate(ctx)
	}
	nativeClient, err := storage.NewClient(ctx, option.WithTokenSource(conf.TokenSource(ctx)))
	return &clientDelegate{nativeClient: nativeClient}, err
}
func (c *clientDelegate) Bucket(bucketName string) BucketHandleWrapper {
	return &bucketDelegate{bucket: c.nativeClient.Bucket(bucketName)}
}