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 }