gitlab.com/evatix-go/core@v1.3.55/coredata/corejson/castingAny.go (about)

     1  package corejson
     2  
     3  import (
     4  	"errors"
     5  	"reflect"
     6  
     7  	"gitlab.com/evatix-go/core/internal/reflectinternal"
     8  )
     9  
    10  type castingAny struct{}
    11  
    12  func (it castingAny) FromToDefault(
    13  	fromAny,
    14  	castedToPtr interface{},
    15  ) (failedOrDeserialized error) {
    16  	return it.FromToOption(
    17  		true,
    18  		fromAny,
    19  		castedToPtr)
    20  }
    21  
    22  func (it castingAny) FromToReflection(
    23  	fromAny,
    24  	castedToPtr interface{},
    25  ) (failedOrDeserialized error) {
    26  	return it.FromToOption(
    27  		true,
    28  		fromAny,
    29  		castedToPtr)
    30  }
    31  
    32  // FromToOption
    33  //
    34  // Giving nil is not support from to.
    35  //
    36  // Warning: must check nil before for from, to both.
    37  //
    38  // Casting from to steps:
    39  //  - reflection first if equal type + right ptr and not nil.
    40  //  - []byte
    41  //  - string
    42  //  - Jsoner
    43  //  - Result
    44  //  - *Result
    45  //  - bytesSerializer
    46  //  - serializerFunc
    47  //  - error to string then cast from json string then to actual unmarshal
    48  func (it castingAny) FromToOption(
    49  	isUseReflection bool,
    50  	fromAny,
    51  	castedToPtr interface{},
    52  ) (failedOrDeserialized error) {
    53  	err, isApplicable := it.reflectionCasting(
    54  		isUseReflection,
    55  		fromAny,
    56  		castedToPtr)
    57  	if isApplicable {
    58  		return err
    59  	}
    60  
    61  	switch castedFrom := fromAny.(type) {
    62  	case []byte:
    63  		return Deserialize.UsingBytes(
    64  			castedFrom,
    65  			castedToPtr)
    66  	case string:
    67  		return Deserialize.UsingBytes(
    68  			[]byte(castedFrom),
    69  			castedToPtr)
    70  	case Jsoner:
    71  		jsonResult := castedFrom.Json()
    72  
    73  		return jsonResult.Deserialize(castedToPtr)
    74  	case Result:
    75  		return castedFrom.Deserialize(castedToPtr)
    76  	case *Result:
    77  		return castedFrom.Deserialize(castedToPtr)
    78  	case bytesSerializer:
    79  		allBytes, parsingErr := castedFrom.Serialize()
    80  
    81  		if parsingErr != nil {
    82  			// usually this error
    83  			// contains all info
    84  			return parsingErr
    85  		}
    86  
    87  		return Deserialize.UsingBytes(
    88  			allBytes,
    89  			castedToPtr)
    90  	case func() ([]byte, error): // serializer func
    91  		jsonResult := NewResult.UsingSerializerFunc(
    92  			castedFrom)
    93  
    94  		return jsonResult.Deserialize(castedToPtr)
    95  	case error:
    96  		if castedFrom == nil {
    97  			return nil
    98  		}
    99  
   100  		parsingErr := Deserialize.UsingBytes(
   101  			[]byte(castedFrom.Error()),
   102  			castedToPtr)
   103  
   104  		if parsingErr != nil {
   105  			return errors.New(
   106  				castedFrom.Error() +
   107  					parsingErr.Error())
   108  		}
   109  
   110  		return nil
   111  	}
   112  
   113  	// from
   114  	serializeJsonResult := Serialize.Apply(
   115  		fromAny)
   116  
   117  	// to
   118  	return serializeJsonResult.Deserialize(
   119  		castedToPtr)
   120  }
   121  
   122  // reflectionCasting
   123  //
   124  //  todo refactor return err
   125  func (it castingAny) reflectionCasting(
   126  	isUseReflection bool,
   127  	fromAny interface{},
   128  	castedToPtr interface{},
   129  ) (err error, isApplicable bool) {
   130  	if !isUseReflection {
   131  		return nil, false
   132  	}
   133  
   134  	if fromAny == nil || castedToPtr == nil {
   135  		// represents interface nil
   136  		// having type to nil will not be captured here.
   137  		// intentionally not taking it -- not a mistake
   138  		return errors.New(
   139  			"cannot cast from to if any from or to is null"), false
   140  	}
   141  
   142  	leftType := reflect.TypeOf(fromAny)
   143  	rightType := reflect.TypeOf(castedToPtr)
   144  
   145  	if leftType != rightType {
   146  		return nil, false
   147  	}
   148  
   149  	isRightPtr := rightType.Kind() == reflect.Ptr
   150  
   151  	if !isRightPtr {
   152  		return nil, false
   153  	}
   154  
   155  	isLeftDefined := reflectinternal.IsNotNull(fromAny)
   156  
   157  	if !isLeftDefined {
   158  		return nil, false
   159  	}
   160  
   161  	isRightDefined := reflectinternal.IsNotNull(castedToPtr)
   162  
   163  	if !isRightDefined {
   164  		return nil, false
   165  	}
   166  
   167  	// ptr, same
   168  	toVal := reflect.
   169  		ValueOf(castedToPtr).
   170  		Elem()
   171  	reflect.
   172  		ValueOf(fromAny).Elem().
   173  		Set(toVal)
   174  
   175  	return nil, true
   176  }
   177  
   178  func (it castingAny) OrDeserializeTo(
   179  	fromAny,
   180  	castedToPtr interface{},
   181  ) (failedOrDeserialized error) {
   182  	return it.FromToDefault(fromAny, castedToPtr)
   183  }