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 }