123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- package registry
- import (
- "path"
- "reflect"
- "runtime"
- )
- // Global
- var (
- Global = New()
- Register = Global.Register
- Descriptions = Global.Descriptions
- GetEntry = Global.Entry
- Add = Global.Add
- )
- // M Alias for map[string]interface{}
- type M = map[string]interface{}
- // R the function registry
- type R struct {
- data map[string]*Entry
- }
- // New creates a new registry
- func New() *R {
- r := &R{map[string]*Entry{}}
- // create a base function here?
- return r
- }
- // Clone an existing registry
- func (r *R) Clone() *R {
- newR := &R{map[string]*Entry{}}
- for k, v := range r.data {
- newR.data[k] = v
- }
- return newR
- }
- // Add unnamed function
- func (r *R) Add(fns ...interface{}) EDescriber {
- b := EDescriber{}
- for _, fn := range fns {
- if reflect.TypeOf(fn).Kind() != reflect.Func {
- return nil
- }
- // Automatic naming
- name := runtime.FuncForPC(reflect.ValueOf(fn).Pointer()).Name()
- name = path.Ext(name)[1:]
- b = append(b, r.Register(name, fn))
- }
- return b
- }
- //Register should be a func only register
- func (r *R) Register(name string, v interface{}) *Entry {
- e := NewEntry(r, v)
- if e.err != nil {
- return e
- }
- r.data[name] = e
- return e
- }
- // Get an entry
- func (r *R) Get(name string, params ...interface{}) (interface{}, error) {
- e, ok := r.data[name]
- if !ok {
- return nil, ErrNotFound
- }
- v := e.fn
- // We already know this is a function
- // and that returns 1 or more values
- vtyp := reflect.TypeOf(v)
- if vtyp.Out(0).Kind() != reflect.Func {
- return v, nil
- }
- // Constructor
- fparam := make([]reflect.Value, len(params))
- for i := range params {
- fparam[i] = reflect.ValueOf(params[i])
- }
- // Call the func and return the thing
- v = reflect.ValueOf(v).Call(fparam)[0].Interface()
- return v, nil
- }
- // Entry fetches entries from the register
- func (r *R) Entry(name string) (*Entry, error) {
- e, ok := r.data[name]
- if !ok {
- return nil, ErrNotFound
- }
- return e, nil
- }
- //Describe named fn
- // Descriptions Description list
- func (r *R) Descriptions() (map[string]Description, error) {
- ret := map[string]Description{}
- for k, e := range r.data {
- ret[k] = *e.Description
- }
- return ret, nil
- }
|