add providers interface
All checks were successful
Go Action / goaction (pull_request) Successful in 1m20s

This commit is contained in:
2026-01-05 14:02:56 +03:00
parent 963a2f1b6c
commit 0cf039a3bc
3 changed files with 98 additions and 1 deletions

View File

@@ -6,6 +6,8 @@ import (
"fmt"
)
var _ Providers = (*Client)(nil)
func Must(providers ...any) *Client {
client, err := New(providers...)
if err != nil {
@@ -18,17 +20,28 @@ func Must(providers ...any) *Client {
func New(providers ...any) (*Client, error) {
client := &Client{
providers: make([]Provider, len(providers)),
name: make(map[string]int),
chain: make([]Providers, 0, len(providers)),
}
for idx, prov := range providers {
var name string
switch current := prov.(type) {
case Provider:
client.providers[idx] = current
name = current.Name()
case Factory:
client.providers[idx] = WrapFactory(current, client)
name = current.Name()
default:
return nil, fmt.Errorf("provier[%d]: %w %T", idx, ErrUnknowType, prov)
}
client.name[name] = idx
if current, ok := prov.(Providers); ok {
client.chain = append(client.chain, current)
}
}
return client, nil
@@ -36,6 +49,8 @@ func New(providers ...any) (*Client, error) {
type Client struct {
providers []Provider
name map[string]int
chain []Providers
}
func (c *Client) Name() string {
@@ -97,3 +112,30 @@ func (c *Client) Bind(ctx context.Context, data Variables) error {
return nil
}
func (c *Client) Provider(name string) (Provider, error) {
if idx, ok := c.name[name]; ok {
return c.providers[idx], nil
}
for _, prov := range c.chain {
if cprov, err := prov.Provider(name); err == nil {
return cprov, nil
}
}
return nil, fmt.Errorf("provider[%v]:%w", c.Name(), ErrNotFound)
}
func (c *Client) Names() []string {
names := make([]string, 0, len(c.providers))
for name := range c.name {
names = append(names, name)
}
for _, prov := range c.chain {
names = append(names, prov.Names()...)
}
return names
}

View File

@@ -2,6 +2,7 @@ package config
import (
"context"
"io"
"gitoa.ru/go-4devs/config/param"
)
@@ -43,6 +44,19 @@ type BindProvider interface {
Bind(ctx context.Context, data Variables) error
}
type DunpProvider interface {
Provider
DumpRefernce(ctx context.Context, w io.Writer, opts Options) error
}
type Providers interface {
Provider
Provider(name string) (Provider, error)
Names() []string
}
type Variables interface {
ByName(name ...string) (Variable, error)
ByParam(filter param.Has) (Variable, error)

View File

@@ -9,7 +9,12 @@ import (
const Name = "chain"
func New(c ...config.Provider) config.BindProvider {
type Providers interface {
config.BindProvider
config.Providers
}
func New(c ...config.Provider) Providers {
return chain(c)
}
@@ -40,3 +45,39 @@ func (c chain) Bind(ctx context.Context, def config.Variables) error {
func (c chain) Name() string {
return Name
}
func (c chain) Provider(name string) (config.Provider, error) {
if c.Name() == name {
return c, nil
}
for _, prov := range c {
if prov.Name() == name {
return prov, nil
}
cprov, ok := prov.(config.Providers)
if !ok {
continue
}
if in, err := cprov.Provider(name); err == nil {
return in, nil
}
}
return nil, fmt.Errorf("prov[%v]:%w", c.Name(), config.ErrNotFound)
}
func (c chain) Names() []string {
names := make([]string, 0, len(c))
for _, prov := range c {
names = append(names, prov.Name())
if cprov, ok := prov.(config.Providers); ok {
names = append(names, cprov.Names()...)
}
}
return names
}