From ab7d036697f45f2142ae649bc950532d51304663 Mon Sep 17 00:00:00 2001 From: Asim Aslam Date: Thu, 6 Jun 2019 11:32:38 +0100 Subject: [PATCH] add init package --- init/default.go | 44 +++++++++++++++++++++++++++++++++++++++ init/init.go | 21 +++++++++++++++++++ init/options.go | 55 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+) create mode 100644 init/default.go create mode 100644 init/init.go create mode 100644 init/options.go diff --git a/init/default.go b/init/default.go new file mode 100644 index 00000000..fa937af0 --- /dev/null +++ b/init/default.go @@ -0,0 +1,44 @@ +package init + +type defaultInit struct { + opts *Options +} + +type stringKey struct{} + +func (i *defaultInit) Init(opts ...Option) error { + if i.opts == nil { + i.opts = new(Options) + } + for _, o := range opts { + if err := i.opts.SetOption(o); err != nil { + return err + } + } + return nil +} + +func (i *defaultInit) Options() *Options { + if i.opts == nil { + i.opts = new(Options) + } + return i.opts +} + +func (i *defaultInit) Value(k interface{}) (interface{}, bool) { + if i.opts == nil { + i.opts = new(Options) + } + return i.opts.Value(k) +} + +func (i *defaultInit) String() string { + if i.opts == nil { + i.opts = new(Options) + } + n, ok := i.opts.Value(stringKey{}) + if ok { + return n.(string) + } + return "defaultInit" +} diff --git a/init/init.go b/init/init.go new file mode 100644 index 00000000..3a4e9fd5 --- /dev/null +++ b/init/init.go @@ -0,0 +1,21 @@ +// Package init is an interface for initialising options +package init + +// Init is used for initialisation +type Init interface { + // Initialise options + Init(...Option) error + // Options returns the current options + Options() *Options + // Value returns an option value + Value(k interface{}) (interface{}, bool) + // The name for who these options exist + String() string +} + +// NewInit returns a new initialiser +func NewInit(opts ...Option) Init { + i := new(defaultInit) + i.Init(opts...) + return i +} diff --git a/init/options.go b/init/options.go new file mode 100644 index 00000000..4cdb9409 --- /dev/null +++ b/init/options.go @@ -0,0 +1,55 @@ +package init + +import ( + "sync" +) + +// Options holds the set of option values and protects them +type Options struct { + sync.RWMutex + values map[interface{}]interface{} +} + +// Option gives access to options +type Option func(o *Options) error + +// Get a value from options +func (o *Options) Value(k interface{}) (interface{}, bool) { + o.RLock() + defer o.RUnlock() + v, ok := o.values[k] + return v, ok +} + +// Set a value in the options +func (o *Options) SetValue(k, v interface{}) error { + o.Lock() + defer o.Unlock() + if o.values == nil { + o.values = map[interface{}]interface{}{} + } + o.values[k] = v + return nil +} + +// SetOption executes an option +func (o *Options) SetOption(op Option) error { + return op(o) +} + +// WithValue allows you to set any value within the options +func WithValue(k, v interface{}) Option { + return func(o *Options) error { + return o.SetValue(k, v) + } +} + +// WithOption gives you the ability to create an option that accesses values +func WithOption(o Option) Option { + return o +} + +// String sets the string +func String(s string) Option { + return WithValue(stringKey{}, s) +}