common/dialer/resolver.go (64 lines of code) (raw):

package dialer import ( "fmt" "os" ) // Resolver resolves a service, getting an address or URL. type Resolver interface { // Resolve resolves a service, getting an address or URL // If a Resolve() call completes successfully but finds no addresses, it will return ("", nil) Resolve() (string, error) // ResolveMany resolves a slice of random addresses or URLs // The int parameter specifies the maximum number of addresses to return. If <= 0, all addresses are returned. // If the call completes successfully but finds no addresses, it will return ([]string{}, nil) ResolveMany(int) ([]string, error) } // ConstantResolver always returns the same value type ConstantResolver struct { s string } // NewConstantResolver creates a ConstantResolver func NewConstantResolver(s string) *ConstantResolver { return &ConstantResolver{s: s} } // Resolve returns the constant func (r *ConstantResolver) Resolve() (string, error) { return r.s, nil } // ResolveMany returns the constant in a slice func (r *ConstantResolver) ResolveMany(n int) ([]string, error) { all := []string{} if r.s != "" { all = append(all, r.s) } return all, nil } // EnvResolver resolves by looking for a key in the OS Environment type EnvResolver struct { key string } // NewEnvResolver creates a new EnvResolver func NewEnvResolver(key string) *EnvResolver { return &EnvResolver{key: key} } // Resolve resolves by looking for a key in the OS Environment func (r *EnvResolver) Resolve() (string, error) { return os.Getenv(r.key), nil } // ResolveMany returns the env key in a slice func (r *EnvResolver) ResolveMany(n int) ([]string, error) { all := []string{} s, err := r.Resolve() if s != "" { all = append(all, s) } return all, err } // CompositeResolves resolves by resolving, in order, via delegates type CompositeResolver struct { dels []Resolver } // NewCompositeResolves creates a new CompositeResolve that resolves by looking through delegates (in order) // A Resolver that returns ("", nil) is ignored, otherwise its result is retuned // CompositeResolver will error if no delegate returned a non-empty result func NewCompositeResolver(dels ...Resolver) *CompositeResolver { return &CompositeResolver{dels: dels} } // Resolve resolves by resolving, in order, via delegates func (r *CompositeResolver) Resolve() (string, error) { for _, r := range r.dels { if s, err := r.Resolve(); s != "" || err != nil { return s, err } } return "", fmt.Errorf("could not resolve: no delegate resolved: %v", r.dels) } // ResolveMany resolves by resolving, in order, via delegates func (r *CompositeResolver) ResolveMany(n int) ([]string, error) { for _, r := range r.dels { if s, err := r.ResolveMany(n); len(s) != 0 || err != nil { return s, err } } return []string{}, fmt.Errorf("could not resolve: no delegate resolved: %v", r.dels) }