Skip to content

Commit

Permalink
added IsNumber helper function
Browse files Browse the repository at this point in the history
  • Loading branch information
adranwit committed Jan 19, 2019
1 parent af2ba7e commit 028b0d7
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 23 deletions.
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
## Jan 19 2019 - v0.10.0
- Added IsNumber helper function
- Enhance Process Struct to handle unexported fields
* Added UnexportedFieldHandler hadnler
* Defined SetUnexportedFieldHandler function
* Defined IgnoreUnexportedFields default handler
- Enhanced GetStructMeta to handle unexported fields
* Added StructMetaFilter
* Defined DefaultStructMetaFilter default
* Defined SetStructMetaFilter






## Jan 15 2019 - v0.9.0
- DownloadWithURL(URL string) (io.ReadCloser, error)

Expand Down
79 changes: 56 additions & 23 deletions converter.go
Original file line number Diff line number Diff line change
Expand Up @@ -528,25 +528,40 @@ func (c *Converter) assignConvertedStruct(target interface{}, inputMap map[strin
initAnonymousStruct(structPointer.Interface())
}
field = aStruct.FieldByName(fieldName)
fieldType, _ := aStruct.Type().FieldByName(fieldName)
if isExported := fieldType.PkgPath == ""; !isExported {
structField := &StructField{
Owner: newStructPointer,
Value: field,
Type: fieldType,
}
if !onUnexportedHandler(structField) {
continue
}
field = structField.Value
}
if _, has := defaultValueMap[fieldName]; has {
delete(defaultValueMap, fieldName)
}

previousLayout := c.DateLayout
if HasTimeLayout(mapping) {
previousLayout := c.DateLayout
c.DateLayout = GetTimeLayout(mapping)
err := c.AssignConverted(field.Addr().Interface(), value)
if err != nil {
c.DateLayout = previousLayout
}

if (!field.CanAddr()) && field.Kind() == reflect.Ptr {
if err := c.AssignConverted(field.Interface(), value); err != nil {
return fmt.Errorf("failed to convert %v to %v due to %v", value, field, err)
}
c.DateLayout = previousLayout

} else {
err := c.AssignConverted(field.Addr().Interface(), value)
if err != nil {
if err := c.AssignConverted(field.Addr().Interface(), value); err != nil {
return fmt.Errorf("failed to convert %v to %v due to %v", value, field, err)
}
}
if HasTimeLayout(mapping) {
c.DateLayout = previousLayout
}
}
}

Expand All @@ -569,7 +584,7 @@ func (c *Converter) assignConvertedStruct(target interface{}, inputMap map[strin
//AssignConverted assign to the target source, target needs to be pointer, input has to be convertible or compatible type
func (c *Converter) AssignConverted(target, source interface{}) error {
if target == nil {
return fmt.Errorf("destinationPointer was nil %v %v", target, source)
return fmt.Errorf("destination Pointer was nil %v %v", target, source)
}
if source == nil {
return nil
Expand Down Expand Up @@ -837,7 +852,6 @@ func (c *Converter) AssignConverted(target, source interface{}) error {
*targetValuePointer = timeValue
return nil
case *interface{}:

(*targetValuePointer) = source
return nil

Expand All @@ -850,17 +864,20 @@ func (c *Converter) AssignConverted(target, source interface{}) error {
if source == nil || !sourceValue.IsValid() || (sourceValue.CanSet() && sourceValue.IsNil()) {
return nil
}

targetIndirectValue := reflect.Indirect(reflect.ValueOf(target))
if sourceValue.IsValid() && sourceValue.Type().AssignableTo(reflect.TypeOf(target)) {
targetIndirectValue.Set(sourceValue.Elem())
return nil
targetValue := reflect.ValueOf(target)
targetIndirectValue := reflect.Indirect(targetValue)
if sourceValue.IsValid() {
if sourceValue.Type().AssignableTo(targetValue.Type()) {
targetIndirectValue.Set(sourceValue.Elem())
return nil
} else if sourceValue.Type().AssignableTo(targetValue.Type().Elem()) {
targetValue.Elem().Set(sourceValue)
return nil
}
}

var targetIndirectPointerType = reflect.TypeOf(target).Elem()
if targetIndirectPointerType.Kind() == reflect.Ptr || targetIndirectPointerType.Kind() == reflect.Slice || targetIndirectPointerType.Kind() == reflect.Map {
targetIndirectPointerType = targetIndirectPointerType.Elem()

}

if targetIndirectValue.Kind() == reflect.Slice || targetIndirectPointerType.Kind() == reflect.Slice {
Expand All @@ -879,8 +896,18 @@ func (c *Converter) AssignConverted(target, source interface{}) error {
if sourceKind == reflect.Map {
return c.assignConvertedMap(target, source, targetIndirectValue, targetIndirectPointerType)
} else if sourceKind == reflect.Struct {
sourceValue = reflect.ValueOf(DereferenceValue(source))
if source == nil {
return nil
}
if sourceValue.Kind() == reflect.Ptr && sourceValue.IsNil() {
return nil
}
targetValue := reflect.ValueOf(target)
if !targetValue.CanInterface() {
return nil
}
return c.assignConvertedMapFromStruct(source, target, sourceValue)

} else if sourceKind == reflect.Slice {
componentType := DereferenceType(DiscoverComponentType(source))
if componentType.ConvertibleTo(reflect.TypeOf(keyValue{})) {
Expand Down Expand Up @@ -923,19 +950,21 @@ func (c *Converter) AssignConverted(target, source interface{}) error {
return nil
}

targetDereferecedType := DereferenceType(target)
targetDeRefType := DereferenceType(target)

for _, candidate := range numericTypes {
if candidate.Kind() == targetDereferecedType.Kind() {
if candidate.Kind() == targetDeRefType.Kind() {
var pointerCount = CountPointers(target)
var compatibleTarget = reflect.New(candidate)
for i := 0; i < pointerCount-1; i++ {
compatibleTarget = reflect.New(compatibleTarget.Type())
}
c.AssignConverted(compatibleTarget.Interface(), source)
targetValue := reflect.ValueOf(target)
targetValue.Elem().Set(compatibleTarget.Elem().Convert(targetValue.Elem().Type()))
return nil
if err := c.AssignConverted(compatibleTarget.Interface(), source); err == nil {
targetValue := reflect.ValueOf(target)
targetValue.Elem().Set(compatibleTarget.Elem().Convert(targetValue.Elem().Type()))
return nil
}

}
}
return fmt.Errorf("Unable to convert type %T into type %T\n\t%v", source, target, source)
Expand Down Expand Up @@ -1078,6 +1107,10 @@ func (c *Converter) assignConvertedMapFromStruct(source, target interface{}, sou
return fmt.Errorf("target %T is not a map", target)
}
return ProcessStruct(source, func(fieldType reflect.StructField, field reflect.Value) error {
if !field.CanInterface() {
return nil
}

value := field.Interface()
if value == nil {
return nil
Expand Down
5 changes: 5 additions & 0 deletions types.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ func IsInt(input interface{}) bool {
return false
}

//IsNumber returns true if type is either float or int
func IsNumber(input interface{}) bool {
return IsFloat(input) || IsInt(input)
}

//IsFloat returns true if input is a float
func IsFloat(input interface{}) bool {
switch input.(type) {
Expand Down

0 comments on commit 028b0d7

Please sign in to comment.