func implementsUnpacker()

in unpack.go [119:159]


func implementsUnpacker(t reflect.Type) bool {
	// ucfg.Config or structures that can be casted to ucfg.Config are not
	// Unpackers.
	if tConfig.ConvertibleTo(chaseTypePointers(t)) {
		return false
	}

	for _, tUnpack := range tUnpackers {
		if t.Implements(tUnpack) {
			return true
		}
	}

	if t.NumMethod() == 0 {
		return false
	}

	// test if object has 'Unpack' method
	method, ok := t.MethodByName("Unpack")
	if !ok {

		return false
	}

	// check method input and output parameters to match the ConfigUnpacker interface:
	// func (to *T) Unpack(cfg *TConfig) error
	//   with T being the method receiver (input paramter 0)
	//   and TConfig being the aliased config type to convert to (input parameter 1)
	paramCountCheck := method.Type.NumIn() == 2 && method.Type.NumOut() == 1
	if !paramCountCheck {
		return false
	}
	if !method.Type.Out(0).Implements(tError) {
		// return variable is not compatible to `error` type
		return false
	}

	// method receiver is known, check config parameters being compatible
	tIn := method.Type.In(1)
	return tConfig.ConvertibleTo(tIn) || tConfigPtr.ConvertibleTo(tIn)
}