...

Source file src/github.com/aws/smithy-go/document/internal/serde/serde.go

Documentation: github.com/aws/smithy-go/document/internal/serde

     1  package serde
     2  
     3  import (
     4  	"reflect"
     5  )
     6  
     7  // Indirect will walk a value's interface or pointer value types. Returning
     8  // the final value or the value a unmarshaler is defined on.
     9  //
    10  // Based on the enoding/json type reflect value type indirection in Go Stdlib
    11  // https://golang.org/src/encoding/json/decode.go Indirect func.
    12  func Indirect(v reflect.Value, decodingNull bool) reflect.Value {
    13  	v0 := v
    14  	haveAddr := false
    15  
    16  	if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() {
    17  		v = v.Addr()
    18  		haveAddr = true
    19  	}
    20  	for {
    21  		if v.Kind() == reflect.Interface && !v.IsNil() {
    22  			e := v.Elem()
    23  			if e.Kind() == reflect.Ptr && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Ptr) {
    24  				haveAddr = false
    25  				v = e
    26  				continue
    27  			}
    28  		}
    29  		if v.Kind() != reflect.Ptr {
    30  			break
    31  		}
    32  		if v.Elem().Kind() != reflect.Ptr && decodingNull && v.CanSet() {
    33  			break
    34  		}
    35  		if v.IsNil() {
    36  			v.Set(reflect.New(v.Type().Elem()))
    37  		}
    38  
    39  		if haveAddr {
    40  			v = v0
    41  			haveAddr = false
    42  		} else {
    43  			v = v.Elem()
    44  		}
    45  	}
    46  
    47  	return v
    48  }
    49  
    50  // PtrToValue given the input value will dereference pointers and returning the element pointed to.
    51  func PtrToValue(in interface{}) interface{} {
    52  	v := reflect.ValueOf(in)
    53  	if v.Kind() == reflect.Ptr {
    54  		v = v.Elem()
    55  	}
    56  	if !v.IsValid() {
    57  		return nil
    58  	}
    59  	if v.Kind() == reflect.Ptr {
    60  		return PtrToValue(v.Interface())
    61  	}
    62  	return v.Interface()
    63  }
    64  
    65  // IsZeroValue returns whether v is the zero-value for its type.
    66  func IsZeroValue(v reflect.Value) bool {
    67  	switch v.Kind() {
    68  	case reflect.Invalid:
    69  		return true
    70  	case reflect.Array:
    71  		return v.Len() == 0
    72  	case reflect.Map, reflect.Slice:
    73  		return v.IsNil()
    74  	case reflect.String:
    75  		return v.Len() == 0
    76  	case reflect.Bool:
    77  		return !v.Bool()
    78  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
    79  		return v.Int() == 0
    80  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
    81  		return v.Uint() == 0
    82  	case reflect.Float32, reflect.Float64:
    83  		return v.Float() == 0
    84  	case reflect.Interface, reflect.Ptr:
    85  		return v.IsNil()
    86  	}
    87  	return false
    88  }
    89  
    90  // ValueElem walks interface and pointer types and returns the underlying element.
    91  func ValueElem(v reflect.Value) reflect.Value {
    92  	switch v.Kind() {
    93  	case reflect.Interface, reflect.Ptr:
    94  		for v.Kind() == reflect.Interface || v.Kind() == reflect.Ptr {
    95  			v = v.Elem()
    96  		}
    97  	}
    98  
    99  	return v
   100  }
   101  

View as plain text