github.com/sandwich-go/boost@v1.3.29/plugin/plugin.go (about)

     1  package plugin
     2  
     3  import (
     4  	"errors"
     5  	"github.com/sandwich-go/boost/xpanic"
     6  	"reflect"
     7  )
     8  
     9  var ErrInvaliPlugin = errors.New("invalid plugin")
    10  
    11  // Plugin 插件
    12  type Plugin interface{}
    13  
    14  // Container 插件容器
    15  type Container interface {
    16  	// Add 添加 Plugin
    17  	Add(Plugin) error
    18  	// MustAdd 添加 Plugin,若为非法的 Plugin,则 panic
    19  	MustAdd(Plugin)
    20  	// Range 遍历所有的 Plugin 并执行函数,若返回 false,则中止遍历
    21  	Range(func(Plugin) bool)
    22  	// Size 插件数量
    23  	Size() int
    24  }
    25  
    26  type container struct {
    27  	plugins []Plugin
    28  	types   []interface{}
    29  }
    30  
    31  func New(types ...interface{}) Container { return &container{types: types} }
    32  func (p *container) MustAdd(pg Plugin)   { xpanic.WhenError(p.Add(pg)) }
    33  func (p *container) Size() int           { return len(p.plugins) }
    34  func (p *container) Add(pg Plugin) error {
    35  	var pType = reflect.TypeOf(pg)
    36  	for _, v := range p.types {
    37  		if pType.Implements(reflect.TypeOf(v).Elem()) {
    38  			p.plugins = append(p.plugins, pg)
    39  			return nil
    40  		}
    41  	}
    42  	return ErrInvaliPlugin
    43  }
    44  
    45  func (p *container) Range(f func(Plugin) bool) {
    46  	for _, plugin := range p.plugins {
    47  		if !f(plugin) {
    48  			return
    49  		}
    50  	}
    51  }