github.com/MontFerret/ferret@v0.18.0/pkg/drivers/driver.go (about)

     1  package drivers
     2  
     3  import (
     4  	"context"
     5  	"io"
     6  
     7  	"github.com/MontFerret/ferret/pkg/runtime/core"
     8  )
     9  
    10  type (
    11  	ctxKey struct{}
    12  
    13  	ctxValue struct {
    14  		opts    *globalOptions
    15  		drivers map[string]Driver
    16  	}
    17  
    18  	Driver interface {
    19  		io.Closer
    20  		Name() string
    21  		Open(ctx context.Context, params Params) (HTMLPage, error)
    22  		Parse(ctx context.Context, params ParseParams) (HTMLPage, error)
    23  	}
    24  )
    25  
    26  func WithContext(ctx context.Context, drv Driver, opts ...GlobalOption) context.Context {
    27  	return withContext(ctx, drv, opts)
    28  }
    29  
    30  func FromContext(ctx context.Context, name string) (Driver, error) {
    31  	_, value := resolveValue(ctx)
    32  
    33  	if name == "" {
    34  		name = value.opts.defaultDriver
    35  	}
    36  
    37  	drv, exists := value.drivers[name]
    38  
    39  	if !exists {
    40  		return nil, core.Error(core.ErrNotFound, name)
    41  	}
    42  
    43  	return drv, nil
    44  }
    45  
    46  func withContext(ctx context.Context, drv Driver, opts []GlobalOption) context.Context {
    47  	ctx, value := resolveValue(ctx)
    48  
    49  	value.drivers[drv.Name()] = drv
    50  
    51  	for _, opt := range opts {
    52  		opt(drv, value.opts)
    53  	}
    54  
    55  	// set first registered driver as a default one
    56  	if value.opts.defaultDriver == "" {
    57  		value.opts.defaultDriver = drv.Name()
    58  	}
    59  
    60  	return ctx
    61  }
    62  
    63  func resolveValue(ctx context.Context) (context.Context, *ctxValue) {
    64  	key := ctxKey{}
    65  	v := ctx.Value(key)
    66  	value, ok := v.(*ctxValue)
    67  
    68  	if !ok {
    69  		value = &ctxValue{
    70  			opts:    &globalOptions{},
    71  			drivers: make(map[string]Driver),
    72  		}
    73  
    74  		return context.WithValue(ctx, key, value), value
    75  	}
    76  
    77  	return ctx, value
    78  }