From 0a55a01f6826b7298be3361b0b4210f79084127b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=AE=A1=E5=AE=9C=E5=B0=A7?= Date: Fri, 22 May 2020 15:31:14 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=84=E8=8C=83=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bind.go | 179 +++++++++++++++++++++++++++++++ container.go | 260 +++++++--------------------------------------- container_test.go | 46 ++++++-- doc.go | 13 +-- error.go | 43 ++++++++ go.mod | 2 +- 6 files changed, 305 insertions(+), 238 deletions(-) create mode 100644 bind.go create mode 100644 error.go diff --git a/bind.go b/bind.go new file mode 100644 index 0000000..da4d559 --- /dev/null +++ b/bind.go @@ -0,0 +1,179 @@ +package container + +import "reflect" + +// BindValue bind a value to container +func (c *containerImpl) BindValue(key string, value interface{}) error { + return c.bindValueOverride(key, value, false) +} + +// HasBoundValue return whether the kay has bound to a value +func (c *containerImpl) HasBoundValue(key string) bool { + c.lock.RLock() + defer c.lock.RUnlock() + + _, ok := c.objects[key] + return ok +} + +func (c *containerImpl) bindValueOverride(key string, value interface{}, override bool) error { + if value == nil { + return buildInvalidArgsError("value is nil") + } + + if key == "" || key == "@" { + return buildInvalidArgsError("key can not be empty or reserved words(@)") + } + + c.lock.Lock() + defer c.lock.Unlock() + + entity := Entity{ + initializeFunc: nil, + key: key, + typ: reflect.TypeOf(value), + value: value, + override: override, + index: len(c.objectSlices), + c: c, + prototype: false, + } + + if original, ok := c.objects[key]; ok { + if !original.override { + return buildRepeatedBindError("key repeated, override is not allowed for this key") + } + + entity.index = original.index + c.objects[key] = &entity + c.objectSlices[original.index] = &entity + + return nil + } + + c.objects[key] = &entity + c.objectSlices = append(c.objectSlices, &entity) + + return nil +} + +// BindValueOverride bind a value to container, if key already exist, then replace it +func (c *containerImpl) BindValueOverride(key string, value interface{}) error { + return c.bindValueOverride(key, value, true) +} + +// MustBindValueOverride bind a value to container, if key already exist, then replace it, if failed, panic it +func (c *containerImpl) MustBindValueOverride(key string, value interface{}) { + c.Must(c.BindValueOverride(key, value)) +} + +// MustBindValue bind a value to container, if failed, panic it +func (c *containerImpl) MustBindValue(key string, value interface{}) { + c.Must(c.BindValue(key, value)) +} + +// HasBound return whether a key's type has bound to an object +func (c *containerImpl) HasBound(key interface{}) bool { + keyTyp := reflect.ValueOf(key).Type() + + c.lock.RLock() + defer c.lock.RUnlock() + + _, ok := c.objects[keyTyp] + return ok +} + +// BindWithKey bind a initialize for object with a key +// initialize func(...) (value, error) +func (c *containerImpl) BindWithKey(key interface{}, initialize interface{}, prototype bool, override bool) error { + if !reflect.ValueOf(initialize).IsValid() { + return buildInvalidArgsError("initialize is nil") + } + + if err := c.isValidKeyKind(reflect.TypeOf(key).Kind()); err != nil { + return err + } + + initializeType := reflect.ValueOf(initialize).Type() + if initializeType.Kind() == reflect.Func { + if initializeType.NumOut() <= 0 { + return buildInvalidArgsError("expect func return values count greater than 0, but got 0") + } + + return c.bindWithOverride(key, initializeType.Out(0), initialize, prototype, override) + } + + initFunc := func() interface{} { return initialize } + return c.bindWithOverride(key, initializeType, initFunc, prototype, override) +} + +// MustBindWithKey bind a initialize for object with a key, if failed then panic +func (c *containerImpl) MustBindWithKey(key interface{}, initialize interface{}, prototype bool, override bool) { + c.Must(c.BindWithKey(key, initialize, prototype, override)) +} + +// Bind bind a initialize for object +// initialize func(...) (value, error) +func (c *containerImpl) Bind(initialize interface{}, prototype bool, override bool) error { + if !reflect.ValueOf(initialize).IsValid() { + return buildInvalidArgsError("initialize is nil") + } + + initializeType := reflect.ValueOf(initialize).Type() + if initializeType.Kind() == reflect.Func { + if initializeType.NumOut() <= 0 { + return buildInvalidArgsError("expect func return values count greater than 0, but got 0") + } + + typ := initializeType.Out(0) + + if err := c.isValidKeyKind(typ.Kind()); err != nil { + return err + } + + return c.bindWithOverride(typ, typ, initialize, prototype, override) + } + + if err := c.isValidKeyKind(initializeType.Kind()); err != nil { + return err + } + + initFunc := func() interface{} { return initialize } + return c.bindWithOverride(initializeType, initializeType, initFunc, prototype, override) +} + +// MustBind bind a initialize, if failed then panic +func (c *containerImpl) MustBind(initialize interface{}, prototype bool, override bool) { + c.Must(c.Bind(initialize, prototype, override)) +} + + +func (c *containerImpl) bindWithOverride(key interface{}, typ reflect.Type, initialize interface{}, prototype bool, override bool) error { + entity := c.newEntity(key, typ, initialize, prototype, override) + + c.lock.Lock() + defer c.lock.Unlock() + + if original, ok := c.objects[key]; ok { + if !original.override { + return buildRepeatedBindError("key repeated, override is not allowed for this key") + } + + entity.index = original.index + c.objects[key] = entity + c.objectSlices[original.index] = entity + + return nil + } + + entity.index = len(c.objectSlices) + + c.objects[key] = entity + c.objectSlices = append(c.objectSlices, entity) + + return nil +} + +func (c *containerImpl) bindWith(key interface{}, typ reflect.Type, initialize interface{}, prototype bool) error { + return c.bindWithOverride(key, typ, initialize, prototype, false) +} \ No newline at end of file diff --git a/container.go b/container.go index 2cd2477..f0548a0 100644 --- a/container.go +++ b/container.go @@ -8,30 +8,16 @@ import ( "unsafe" ) -// ResolveError is a error when container can not resolve a object -type ResolveError struct { - err error -} - -func newResolveError(err error) ResolveError { - return ResolveError{err: err} -} - -// Error return the error string -func (re ResolveError) Error() string { - return re.err.Error() -} - // Entity represent a entity in container type Entity struct { lock sync.RWMutex - key interface{} // entity key - initializeFunc interface{} // initializeFunc is a func to initialize entity - value interface{} - typ reflect.Type - index int // the index in the container - override bool // identify whether the entity can be override + key interface{} // entity key + initializeFunc interface{} // initializeFunc is a func to initialize entity + value interface{} // the value of initializeFunc + typ reflect.Type // the type of value + index int // the index in the container + override bool // identify whether the entity can be override prototype bool c *containerImpl @@ -67,14 +53,16 @@ func (e *Entity) createValue(provider func() []*Entity) (interface{}, error) { returnValues := reflect.ValueOf(e.initializeFunc).Call(argValues) if len(returnValues) <= 0 { - return nil, ErrInvalidReturnValueCount("expect greater than 0, got 0") + return nil, buildInvalidReturnValueCountError("expect greater than 0, got 0") } if len(returnValues) > 1 && !returnValues[1].IsNil() && returnValues[1].Interface() != nil { - err, ok := returnValues[1].Interface().(error) - if ok { + if err, ok := returnValues[1].Interface().(error); ok { return nil, err } + + // 如果第二个返回值不是 error,则强制转换为 error + return nil, fmt.Errorf("%v", returnValues[1].Interface()) } return returnValues[0].Interface(), nil @@ -230,76 +218,6 @@ func (c *containerImpl) MustSingletonWithKey(key interface{}, initialize interfa c.Must(c.SingletonWithKey(key, initialize)) } -// BindValue bind a value to container -func (c *containerImpl) BindValue(key interface{}, value interface{}) error { - return c.bindValueOverride(key, value, false) -} - -// HasBindValue return whether the kay has bound to a value -func (c *containerImpl) HasBindValue(key interface{}) bool { - c.lock.RLock() - defer c.lock.RUnlock() - - _, ok := c.objects[key] - return ok -} - -func (c *containerImpl) bindValueOverride(key interface{}, value interface{}, override bool) error { - if value == nil { - return ErrInvalidArgs("value is nil") - } - - c.lock.Lock() - defer c.lock.Unlock() - - entity := Entity{ - initializeFunc: nil, - key: key, - typ: reflect.TypeOf(value), - value: value, - override: override, - index: len(c.objectSlices), - c: c, - prototype: false, - } - - if original, ok := c.objects[key]; ok { - if !override { - return ErrRepeatedBind("key repeated") - } - - if !original.override { - return ErrRepeatedBind("key repeated, override is not allowed for this key") - } - - entity.index = original.index - c.objects[key] = &entity - c.objectSlices[original.index] = &entity - - return nil - } - - c.objects[key] = &entity - c.objectSlices = append(c.objectSlices, &entity) - - return nil -} - -// BindValueOverride bind a value to container, if key already exist, then replace it -func (c *containerImpl) BindValueOverride(key interface{}, value interface{}) error { - return c.bindValueOverride(key, value, true) -} - -// MustBindValueOverride bind a value to container, if key already exist, then replace it, if failed, panic it -func (c *containerImpl) MustBindValueOverride(key interface{}, value interface{}) { - c.Must(c.BindValueOverride(key, value)) -} - -// MustBindValue bind a value to container, if failed, panic it -func (c *containerImpl) MustBindValue(key interface{}, value interface{}) { - c.Must(c.BindValue(key, value)) -} - // ServiceProvider create a provider from initializes func (c *containerImpl) ServiceProvider(initializes ...interface{}) (func() []*Entity, error) { entities := make([]*Entity, len(initializes)) @@ -320,12 +238,12 @@ func (c *containerImpl) ServiceProvider(initializes ...interface{}) (func() []*E // newEntityWrapper create a new entity func (c *containerImpl) newEntityWrapper(initialize interface{}, prototype bool) (*Entity, error) { if !reflect.ValueOf(initialize).IsValid() { - return nil, ErrInvalidArgs("initialize is nil") + return nil, buildInvalidArgsError("initialize is nil") } initializeType := reflect.ValueOf(initialize).Type() if initializeType.NumOut() <= 0 { - return nil, ErrInvalidArgs("expect func return values count greater than 0, but got 0") + return nil, buildInvalidArgsError("expect func return values count greater than 0, but got 0") } typ := initializeType.Out(0) @@ -346,51 +264,14 @@ func (c *containerImpl) newEntity(key interface{}, typ reflect.Type, initialize return &entity } -// HasBind return whether a key's type has bound to an object -func (c *containerImpl) HasBind(key interface{}) bool { - keyTyp := reflect.ValueOf(key).Type() - - c.lock.RLock() - defer c.lock.RUnlock() - - _, ok := c.objects[keyTyp] - return ok -} - -// Bind bind a initialize for object -// initialize func(...) (value, error) -func (c *containerImpl) Bind(initialize interface{}, prototype bool, override bool) error { - if !reflect.ValueOf(initialize).IsValid() { - return ErrInvalidArgs("initialize is nil") - } - - initializeType := reflect.ValueOf(initialize).Type() - if initializeType.Kind() == reflect.Func { - if initializeType.NumOut() <= 0 { - return ErrInvalidArgs("expect func return values count greater than 0, but got 0") - } - - typ := initializeType.Out(0) - return c.bindWithOverride(typ, typ, initialize, prototype, override) - } - - initFunc := func() interface{} { return initialize } - return c.bindWithOverride(initializeType, initializeType, initFunc, prototype, override) -} - -// MustBind bind a initialize, if failed then panic -func (c *containerImpl) MustBind(initialize interface{}, prototype bool, override bool) { - c.Must(c.Bind(initialize, prototype, override)) -} - func (c *containerImpl) AutoWire(object interface{}) error { if !reflect.ValueOf(object).IsValid() { - return ErrInvalidArgs("object is nil") + return buildInvalidArgsError("object is nil") } valRef := reflect.ValueOf(object) if valRef.Kind() != reflect.Ptr { - return ErrInvalidArgs("object must be a pointer to struct object") + return buildInvalidArgsError("object must be a pointer to struct object") } structValue := valRef.Elem() @@ -398,7 +279,7 @@ func (c *containerImpl) AutoWire(object interface{}) error { for i := 0; i < structType.NumField(); i++ { field := structType.Field(i) tag := field.Tag.Get("autowire") - if tag == "" { + if tag == "" || tag == "-" { continue } @@ -424,26 +305,6 @@ func (c *containerImpl) AutoWire(object interface{}) error { return nil } -// BindWithKey bind a initialize for object with a key -// initialize func(...) (value, error) -func (c *containerImpl) BindWithKey(key interface{}, initialize interface{}, prototype bool, override bool) error { - if !reflect.ValueOf(initialize).IsValid() { - return ErrInvalidArgs("initialize is nil") - } - - initializeType := reflect.ValueOf(initialize).Type() - if initializeType.NumOut() <= 0 { - return ErrInvalidArgs("expect func return values count greater than 0, but got 0") - } - - return c.bindWithOverride(key, initializeType.Out(0), initialize, prototype, override) -} - -// MustBindWithKey bind a initialize for object with a key, if failed then panic -func (c *containerImpl) MustBindWithKey(key interface{}, initialize interface{}, prototype bool, override bool) { - c.Must(c.BindWithKey(key, initialize, prototype, override)) -} - // Resolve inject args for func by callback // callback func(...) func (c *containerImpl) Resolve(callback interface{}) error { @@ -461,7 +322,7 @@ func (c *containerImpl) MustResolve(callback interface{}) { func (c *containerImpl) ResolveWithError(callback interface{}) error { results, err := c.Call(callback) if err != nil { - return newResolveError(err) + return err } if len(results) == 1 && results[0] != nil { @@ -477,7 +338,7 @@ func (c *containerImpl) ResolveWithError(callback interface{}) error { func (c *containerImpl) CallWithProvider(callback interface{}, provider func() []*Entity) ([]interface{}, error) { callbackValue := reflect.ValueOf(callback) if !callbackValue.IsValid() { - return nil, ErrInvalidArgs("callback is nil") + return nil, buildInvalidArgsError("callback is nil") } args, err := c.funcArgs(callbackValue.Type(), provider) @@ -515,33 +376,23 @@ func (c *containerImpl) get(key interface{}, provider func() []*Entity) (interfa if provider != nil { for _, obj := range provider() { - if obj.key == key || obj.key == keyReflectType { return obj.Value(provider) } - - // if obj.typ.AssignableTo(keyReflectType) { - // return obj.Value(provider) - // } } } for _, obj := range c.objectSlices { - if obj.key == key || obj.key == keyReflectType { return obj.Value(provider) } - - // if obj.typ.AssignableTo(keyReflectType) { - // return obj.Value(provider) - // } } if c.parent != nil { return c.parent.Get(key) } - return nil, ErrObjectNotFound(fmt.Sprintf("key=%s", key)) + return nil, buildObjectNotFoundError(fmt.Sprintf("key=%s not found", key)) } // MustGet get instance by key from container @@ -554,40 +405,6 @@ func (c *containerImpl) MustGet(key interface{}) interface{} { return res } -func (c *containerImpl) bindWithOverride(key interface{}, typ reflect.Type, initialize interface{}, prototype bool, override bool) error { - c.lock.Lock() - defer c.lock.Unlock() - - if original, ok := c.objects[key]; ok { - if !override { - return ErrRepeatedBind("key repeated") - } - - if !original.override { - return ErrRepeatedBind("key repeated, override is not allowed for this key") - } - - entity := c.newEntity(key, typ, initialize, prototype, override) - entity.index = original.index - c.objects[key] = entity - c.objectSlices[original.index] = entity - - return nil - } - - entity := c.newEntity(key, typ, initialize, prototype, override) - entity.index = len(c.objectSlices) - - c.objects[key] = entity - c.objectSlices = append(c.objectSlices, entity) - - return nil -} - -func (c *containerImpl) bindWith(key interface{}, typ reflect.Type, initialize interface{}, prototype bool) error { - return c.bindWithOverride(key, typ, initialize, prototype, false) -} - func (c *containerImpl) funcArgs(t reflect.Type, provider func() []*Entity) ([]reflect.Value, error) { argsSize := t.NumIn() argValues := make([]reflect.Value, argsSize) @@ -607,7 +424,7 @@ func (c *containerImpl) funcArgs(t reflect.Type, provider func() []*Entity) ([]r func (c *containerImpl) instanceOfType(t reflect.Type, provider func() []*Entity) (reflect.Value, error) { arg, err := c.get(t, provider) if err != nil { - return reflect.Value{}, ErrArgNotInstanced(err.Error()) + return reflect.Value{}, buildArgNotInstancedError(err.Error()) } return reflect.ValueOf(arg), nil @@ -626,31 +443,24 @@ func (c *containerImpl) Keys() []interface{} { return results } -func isErrorType(t reflect.Type) bool { - return t.Implements(reflect.TypeOf((*error)(nil)).Elem()) -} - -// ErrObjectNotFound is an error object represent object not found -func ErrObjectNotFound(msg string) error { - return fmt.Errorf("the object can not be found in container: %s", msg) -} +// CanOverride returns whether the key can be override +func (c *containerImpl) CanOverride(key interface{}) (bool, error) { + c.lock.RLock() + defer c.lock.RUnlock() -// ErrArgNotInstanced is an error object represent arg not instanced -func ErrArgNotInstanced(msg string) error { - return fmt.Errorf("the arg can not be found in container: %s", msg) -} + obj, ok := c.objects[key] + if !ok { + return true, buildObjectNotFoundError(fmt.Sprintf("key=%v not found", key)) + } -// ErrInvalidReturnValueCount is an error object represent return values count not match -func ErrInvalidReturnValueCount(msg string) error { - return fmt.Errorf("invalid return value count: %s", msg) + return obj.override, nil } -// ErrRepeatedBind is an error object represent bind a value repeated -func ErrRepeatedBind(msg string) error { - return fmt.Errorf("can not bind a value with repeated key: %s", msg) -} +// isValidKeyKind 判断类型是否允许作为key +func (c *containerImpl) isValidKeyKind(kind reflect.Kind) error { + if kind == reflect.Struct || kind == reflect.Interface || kind == reflect.Ptr { + return nil + } -// ErrInvalidArgs is an error object represent invalid args -func ErrInvalidArgs(msg string) error { - return fmt.Errorf("invalid args: %s", msg) + return buildInvalidArgsError(fmt.Sprintf("the type of key can not be a %v", kind)) } diff --git a/container_test.go b/container_test.go index 6c304cd..f6dd502 100644 --- a/container_test.go +++ b/container_test.go @@ -38,6 +38,7 @@ type UserRepo struct { var expectedValue = "get user from connection: root:root@/my_db?charset=utf8" +// TestPrototype 测试原型模式 func TestPrototype(t *testing.T) { c := container.New() @@ -102,6 +103,7 @@ func TestPrototype(t *testing.T) { } } +// TestInterfaceInjection 测试接口注入 func TestInterfaceInjection(t *testing.T) { c := container.New() c.MustBindValue("conn_str", "root:root@/my_db?charset=utf8") @@ -143,6 +145,7 @@ func TestInterfaceInjection(t *testing.T) { } } +// TestWithContext 测试默认添加 Context 实例 func TestWithContext(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) defer cancel() @@ -164,6 +167,7 @@ type TestObject struct { Name string } +// TestWithProvider 测试使用 Provider 提供额外的实例配置 func TestWithProvider(t *testing.T) { c := container.New() c.MustBindValue("conn_str", "root:root@/my_db?charset=utf8") @@ -199,6 +203,7 @@ func TestWithProvider(t *testing.T) { } } +// TestBindValue 测试直接绑定实体对象 func TestBindValue(t *testing.T) { c := container.New() userRepoStruct := UserRepo{connStr: "user struct"} @@ -220,6 +225,7 @@ func TestBindValue(t *testing.T) { }) } +// TestExtend 测试容器扩展 func TestExtend(t *testing.T) { c := container.New() c.MustBindValue("conn_str", "root:root@/my_db?charset=utf8") @@ -267,40 +273,45 @@ func TestExtend(t *testing.T) { } } +// --------------- 测试实例覆盖 ------------------ + type InterfaceDemo interface { - Hello() string + String() string } type demo1 struct{} -func (d demo1) Hello() string { return "demo1" } +func (d demo1) String() string { return "demo1" } type demo2 struct{} -func (d demo2) Hello() string { return "demo2" } +func (d demo2) String() string { return "demo2" } func TestContainerImpl_Override(t *testing.T) { c := container.New() - c.MustSingleton(func() InterfaceDemo { + c.MustSingletonOverride(func() InterfaceDemo { return demo1{} }) - c.MustSingletonOverride(func() InterfaceDemo { + c.MustSingleton(func() InterfaceDemo { return demo2{} }) c.MustResolve(func(demo InterfaceDemo) { - if "demo2" != demo.Hello() { + if "demo2" != demo.String() { t.Error("test failed") } }) } +// ----------- 测试自动注入 -------------- + type UserManager struct { UserRepo *UserRepo `autowire:"@" json:"-"` field1 string `autowire:"version"` + Field2 string `json:"field2"` } func TestContainerImpl_AutoWire(t *testing.T) { @@ -325,4 +336,27 @@ func TestContainerImpl_AutoWire(t *testing.T) { if manager.field1 != "1.0.1" { t.Error("test failed") } + + if manager.Field2 != "" { + t.Error("test failed") + } +} + +// ------------- 测试 Keys ------------- + +func TestContainerImpl_Keys(t *testing.T) { + c := container.New() + c.MustSingleton(func() InterfaceDemo { return demo1{} }) + c.MustSingleton(demo2{}) + c.MustBindValue("key1", "value1") + c.MustBindValue("key2", 1233) + c.MustBindValue("container.Container", "与接口同名的value") + + for _, k := range c.Keys() { + fmt.Printf("%-50v: type=%v, val=%v\n", k, reflect.ValueOf(k).Type(), c.MustGet(k)) + } + + if c.MustGet("container.Container") != "与接口同名的value" { + t.Error("test failed") + } } diff --git a/doc.go b/doc.go index 9db23de..589fd21 100644 --- a/doc.go +++ b/doc.go @@ -48,13 +48,13 @@ type Container interface { SingletonWithKeyOverride(key interface{}, initialize interface{}) error MustSingletonWithKeyOverride(key interface{}, initialize interface{}) - HasBindValue(key interface{}) bool - BindValue(key interface{}, value interface{}) error - MustBindValue(key interface{}, value interface{}) - BindValueOverride(key interface{}, value interface{}) error - MustBindValueOverride(key interface{}, value interface{}) + HasBoundValue(key string) bool + BindValue(key string, value interface{}) error + MustBindValue(key string, value interface{}) + BindValueOverride(key string, value interface{}) error + MustBindValueOverride(key string, value interface{}) - HasBind(key interface{}) bool + HasBound(key interface{}) bool Bind(initialize interface{}, prototype bool, override bool) error MustBind(initialize interface{}, prototype bool, override bool) BindWithKey(key interface{}, initialize interface{}, prototype bool, override bool) error @@ -78,4 +78,5 @@ type Container interface { ExtendFrom(parent Container) Must(err error) Keys() []interface{} + CanOverride(key interface{}) (bool, error) } diff --git a/error.go b/error.go new file mode 100644 index 0000000..dfe49a0 --- /dev/null +++ b/error.go @@ -0,0 +1,43 @@ +package container + +import ( + "errors" + "fmt" +) + +var ( + ErrObjectNotFound = errors.New("not found in container") + ErrArgsNotInstanced = errors.New("args not instanced") + ErrInvalidReturnValueCount = errors.New("invalid return value count") + ErrRepeatedBind = errors.New("repeated bind") + ErrInvalidArgs = errors.New("invalid args") +) + +//func isErrorType(t reflect.Type) bool { +// return t.Implements(reflect.TypeOf((*error)(nil)).Elem()) +//} + +// buildObjectNotFoundError is an error object represent object not found +func buildObjectNotFoundError(msg string) error { + return fmt.Errorf("%w: %s", ErrObjectNotFound, msg) +} + +// buildArgNotInstancedError is an error object represent arg not instanced +func buildArgNotInstancedError(msg string) error { + return fmt.Errorf("%w: %s", ErrArgsNotInstanced, msg) +} + +// buildInvalidReturnValueCountError is an error object represent return values count not match +func buildInvalidReturnValueCountError(msg string) error { + return fmt.Errorf("%w: %s", ErrInvalidReturnValueCount, msg) +} + +// buildRepeatedBindError is an error object represent bind a value repeated +func buildRepeatedBindError(msg string) error { + return fmt.Errorf("%w: %s", ErrRepeatedBind, msg) +} + +// buildInvalidArgsError is an error object represent invalid args +func buildInvalidArgsError(msg string) error { + return fmt.Errorf("%w: %s", ErrInvalidArgs, msg) +} diff --git a/go.mod b/go.mod index cc8fd2c..06b4666 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,3 @@ module github.com/mylxsw/container -go 1.12 +go 1.13