gopkg.in/rethinkdb/rethinkdb-go.v6@v6.2.2/encoding/encoder_types.go (about) 1 package encoding 2 3 import ( 4 "encoding/base64" 5 "fmt" 6 "math" 7 "reflect" 8 "time" 9 ) 10 11 // newTypeEncoder constructs an encoderFunc for a type. 12 // The returned encoder only checks CanAddr when allowAddr is true. 13 func newTypeEncoder(t reflect.Type, allowAddr bool) encoderFunc { 14 if t.Implements(marshalerType) { 15 return marshalerEncoder 16 } 17 if t.Kind() != reflect.Ptr && allowAddr { 18 if reflect.PtrTo(t).Implements(marshalerType) { 19 return newCondAddrEncoder(addrMarshalerEncoder, newTypeEncoder(t, false)) 20 } 21 } 22 23 // Check for psuedo-types first 24 switch t { 25 case timeType: 26 return timePseudoTypeEncoder 27 } 28 29 switch t.Kind() { 30 case reflect.Bool: 31 return boolEncoder 32 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 33 return intEncoder 34 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 35 return uintEncoder 36 case reflect.Float32: 37 return float32Encoder 38 case reflect.Float64: 39 return floatEncoder 40 case reflect.String: 41 return stringEncoder 42 case reflect.Interface: 43 return interfaceEncoder 44 case reflect.Struct: 45 return newStructEncoder(t) 46 case reflect.Map: 47 return newMapEncoder(t) 48 case reflect.Slice: 49 return newSliceEncoder(t) 50 case reflect.Array: 51 return newArrayEncoder(t) 52 case reflect.Ptr: 53 return newPtrEncoder(t) 54 case reflect.Func: 55 // functions are a special case as they can be used internally for 56 // optional arguments. Just return the raw function, if somebody tries 57 // to pass a function to the database the JSON marshaller will catch this 58 // anyway. 59 return funcEncoder 60 default: 61 return unsupportedTypeEncoder 62 } 63 } 64 65 func invalidValueEncoder(v reflect.Value) (interface{}, error) { 66 return nil, nil 67 } 68 69 func doNothingEncoder(v reflect.Value) (interface{}, error) { 70 return v.Interface(), nil 71 } 72 73 func marshalerEncoder(v reflect.Value) (interface{}, error) { 74 if v.Kind() == reflect.Ptr && v.IsNil() { 75 return nil, nil 76 } 77 m := v.Interface().(Marshaler) 78 ev, err := m.MarshalRQL() 79 if err != nil { 80 return nil, &MarshalerError{v.Type(), err} 81 } 82 83 return ev, nil 84 } 85 86 func addrMarshalerEncoder(v reflect.Value) (interface{}, error) { 87 va := v.Addr() 88 if va.IsNil() { 89 return nil, nil 90 } 91 m := va.Interface().(Marshaler) 92 ev, err := m.MarshalRQL() 93 if err != nil { 94 return nil, &MarshalerError{v.Type(), err} 95 } 96 97 return ev, nil 98 } 99 100 func boolEncoder(v reflect.Value) (interface{}, error) { 101 if v.Bool() { 102 return true, nil 103 } else { 104 return false, nil 105 } 106 } 107 108 func intEncoder(v reflect.Value) (interface{}, error) { 109 return v.Int(), nil 110 } 111 112 func uintEncoder(v reflect.Value) (interface{}, error) { 113 return v.Uint(), nil 114 } 115 116 func floatEncoder(v reflect.Value) (interface{}, error) { 117 return v.Float(), nil 118 } 119 120 func float32Encoder(v reflect.Value) (interface{}, error) { 121 return float32(v.Float()), nil 122 } 123 124 func stringEncoder(v reflect.Value) (interface{}, error) { 125 return v.String(), nil 126 } 127 128 func interfaceEncoder(v reflect.Value) (interface{}, error) { 129 if v.IsNil() { 130 return nil, nil 131 } 132 return encode(v.Elem()) 133 } 134 135 func funcEncoder(v reflect.Value) (interface{}, error) { 136 if v.IsNil() { 137 return nil, nil 138 } 139 return v.Interface(), nil 140 } 141 142 func asStringEncoder(v reflect.Value) (interface{}, error) { 143 return fmt.Sprintf("%v", v.Interface()), nil 144 } 145 146 func unsupportedTypeEncoder(v reflect.Value) (interface{}, error) { 147 return nil, &UnsupportedTypeError{v.Type()} 148 } 149 150 type structEncoder struct { 151 fields []field 152 fieldEncs []encoderFunc 153 } 154 155 func (se *structEncoder) encode(v reflect.Value) (interface{}, error) { 156 m := make(map[string]interface{}) 157 for i, f := range se.fields { 158 fv := fieldByIndex(v, f.index) 159 if !fv.IsValid() || f.omitEmpty && se.isEmptyValue(fv) { 160 continue 161 } 162 163 encField, err := se.fieldEncs[i](fv) 164 if err != nil { 165 return nil, err 166 } 167 168 // If this field is a referenced field then attempt to extract the value. 169 if f.reference { 170 // Override the encoded field with the referenced field 171 encField = getReferenceField(f, v, encField) 172 } 173 174 if f.compound { 175 compoundField, ok := m[f.name].([]interface{}) 176 if !ok { 177 compoundField = make([]interface{}, f.compoundIndex+1) 178 } else if len(compoundField) < f.compoundIndex+1 { 179 tmp := make([]interface{}, f.compoundIndex+1) 180 copy(tmp, compoundField) 181 compoundField = tmp 182 } 183 184 compoundField[f.compoundIndex] = encField 185 encField = compoundField 186 } 187 188 m[f.name] = encField 189 } 190 191 return m, nil 192 } 193 194 func getReferenceField(f field, v reflect.Value, encField interface{}) interface{} { 195 refName := f.name 196 if f.refName != "" { 197 refName = f.refName 198 } 199 200 encFields, isArray := encField.([]interface{}) 201 if isArray { 202 refVals := make([]interface{}, len(encFields)) 203 for i, e := range encFields { 204 refVals[i] = extractValue(e, v, f.name, refName) 205 } 206 return refVals 207 } 208 refVal := extractValue(encField, v, f.name, refName) 209 return refVal 210 } 211 212 func extractValue(encField interface{}, v reflect.Value, name string, refName string) interface{} { 213 // referenced fields can only handle maps so return an error if the 214 // encoded field is of a different type 215 m, ok := encField.(map[string]interface{}) 216 if !ok { 217 err := fmt.Errorf("Error refing field %s in %s, expected object but got %t", refName, name, encField) 218 panic(&MarshalerError{v.Type(), err}) 219 } 220 refVal, ok := m[refName] 221 if !ok { 222 err := fmt.Errorf("Error refing field %s in %s, could not find referenced field", refName, name) 223 panic(&MarshalerError{v.Type(), err}) 224 } 225 return refVal 226 } 227 228 func (se *structEncoder) isEmptyValue(v reflect.Value) bool { 229 if v.Type() == timeType { 230 return v.Interface().(time.Time) == time.Time{} 231 } 232 233 return isEmptyValue(v) 234 } 235 236 func newStructEncoder(t reflect.Type) encoderFunc { 237 fields := cachedTypeFields(t) 238 se := &structEncoder{ 239 fields: fields, 240 fieldEncs: make([]encoderFunc, len(fields)), 241 } 242 for i, f := range fields { 243 se.fieldEncs[i] = typeEncoder(typeByIndex(t, f.index)) 244 } 245 return se.encode 246 } 247 248 type mapEncoder struct { 249 keyEnc, elemEnc encoderFunc 250 } 251 252 func (me *mapEncoder) encode(v reflect.Value) (interface{}, error) { 253 if v.IsNil() { 254 return nil, nil 255 } 256 257 m := make(map[string]interface{}) 258 259 for _, k := range v.MapKeys() { 260 encV, err := me.elemEnc(v.MapIndex(k)) 261 if err != nil { 262 return nil, err 263 } 264 encK, err := me.keyEnc(k) 265 if err != nil { 266 return nil, err 267 } 268 m[encK.(string)] = encV 269 } 270 271 return m, nil 272 } 273 274 func newMapEncoder(t reflect.Type) encoderFunc { 275 var keyEnc encoderFunc 276 switch t.Key().Kind() { 277 case reflect.Bool: 278 keyEnc = asStringEncoder 279 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 280 keyEnc = asStringEncoder 281 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 282 keyEnc = asStringEncoder 283 case reflect.Float32, reflect.Float64: 284 keyEnc = asStringEncoder 285 case reflect.String: 286 keyEnc = stringEncoder 287 case reflect.Interface: 288 keyEnc = asStringEncoder 289 default: 290 return unsupportedTypeEncoder 291 } 292 293 me := &mapEncoder{keyEnc, typeEncoder(t.Elem())} 294 return me.encode 295 } 296 297 // sliceEncoder just wraps an arrayEncoder, checking to make sure the value isn't nil. 298 type sliceEncoder struct { 299 arrayEnc encoderFunc 300 } 301 302 func (se *sliceEncoder) encode(v reflect.Value) (interface{}, error) { 303 if v.IsNil() { 304 return []interface{}(nil), nil 305 } 306 return se.arrayEnc(v) 307 } 308 309 func newSliceEncoder(t reflect.Type) encoderFunc { 310 // Byte slices get special treatment; arrays don't. 311 if t.Elem().Kind() == reflect.Uint8 { 312 return encodeByteSlice 313 } 314 enc := &sliceEncoder{newArrayEncoder(t)} 315 return enc.encode 316 } 317 318 type arrayEncoder struct { 319 elemEnc encoderFunc 320 } 321 322 func (ae *arrayEncoder) encode(v reflect.Value) (interface{}, error) { 323 n := v.Len() 324 325 a := make([]interface{}, n) 326 for i := 0; i < n; i++ { 327 var err error 328 a[i], err = ae.elemEnc(v.Index(i)) 329 if err != nil { 330 return nil, err 331 } 332 } 333 334 return a, nil 335 } 336 337 func newArrayEncoder(t reflect.Type) encoderFunc { 338 if t.Elem().Kind() == reflect.Uint8 { 339 return encodeByteArray 340 } 341 enc := &arrayEncoder{typeEncoder(t.Elem())} 342 return enc.encode 343 } 344 345 type ptrEncoder struct { 346 elemEnc encoderFunc 347 } 348 349 func (pe *ptrEncoder) encode(v reflect.Value) (interface{}, error) { 350 if v.IsNil() { 351 return nil, nil 352 } 353 return pe.elemEnc(v.Elem()) 354 } 355 356 func newPtrEncoder(t reflect.Type) encoderFunc { 357 enc := &ptrEncoder{typeEncoder(t.Elem())} 358 return enc.encode 359 } 360 361 type condAddrEncoder struct { 362 canAddrEnc, elseEnc encoderFunc 363 } 364 365 func (ce *condAddrEncoder) encode(v reflect.Value) (interface{}, error) { 366 if v.CanAddr() { 367 return ce.canAddrEnc(v) 368 } else { 369 return ce.elseEnc(v) 370 } 371 } 372 373 // newCondAddrEncoder returns an encoder that checks whether its value 374 // CanAddr and delegates to canAddrEnc if so, else to elseEnc. 375 func newCondAddrEncoder(canAddrEnc, elseEnc encoderFunc) encoderFunc { 376 enc := &condAddrEncoder{canAddrEnc: canAddrEnc, elseEnc: elseEnc} 377 return enc.encode 378 } 379 380 // Pseudo-type encoders 381 382 // Encode a time.Time value to the TIME RQL type 383 func timePseudoTypeEncoder(v reflect.Value) (interface{}, error) { 384 t := v.Interface().(time.Time) 385 386 timeVal := float64(t.UnixNano()) / float64(time.Second) 387 388 // use seconds-since-epoch precision if time.Time `t` 389 // is before the oldest nanosecond time 390 if t.Before(time.Unix(0, math.MinInt64)) { 391 timeVal = float64(t.Unix()) 392 } 393 394 return map[string]interface{}{ 395 "$reql_type$": "TIME", 396 "epoch_time": timeVal, 397 "timezone": t.Format("-07:00"), 398 }, nil 399 } 400 401 // Encode a byte slice to the BINARY RQL type 402 func encodeByteSlice(v reflect.Value) (interface{}, error) { 403 var b []byte 404 if !v.IsNil() { 405 b = v.Bytes() 406 } 407 408 dst := make([]byte, base64.StdEncoding.EncodedLen(len(b))) 409 base64.StdEncoding.Encode(dst, b) 410 411 return map[string]interface{}{ 412 "$reql_type$": "BINARY", 413 "data": string(dst), 414 }, nil 415 } 416 417 // Encode a byte array to the BINARY RQL type 418 func encodeByteArray(v reflect.Value) (interface{}, error) { 419 b := make([]byte, v.Len()) 420 for i := 0; i < v.Len(); i++ { 421 b[i] = v.Index(i).Interface().(byte) 422 } 423 424 dst := make([]byte, base64.StdEncoding.EncodedLen(len(b))) 425 base64.StdEncoding.Encode(dst, b) 426 427 return map[string]interface{}{ 428 "$reql_type$": "BINARY", 429 "data": string(dst), 430 }, nil 431 }