ソースを参照

codec: provide TimeNotBuiltin option to allow time.Time be handled in custom way

Previously, time.Time was handled either in a standard way (based on the format)
or in in a custom way that defaulted to using a custom extension,
or allowing the encoding.(Binary|Text)(M|Unm)arshaler implementation to be used.

Around Nov 2017, that was changed, as all formats provide a standard way or a
standardized extension format for encoding time.Time.

The option: TimeNotBuiltin, now allows users the option to customize how time.Time
is handled (as it was before).

Fixes #269
Ugorji Nwoke 7 年 前
コミット
037e5aa7ef
2 ファイル変更17 行追加5 行削除
  1. 4 4
      codec/gen.go
  2. 13 1
      codec/helper.go

+ 4 - 4
codec/gen.go

@@ -740,8 +740,8 @@ func (x *genRunner) enc(varname string, t reflect.Type) {
 	defer func() { x.line("}") }() //end if block
 
 	if t == timeTyp {
-		x.linef("} else { r.EncodeTime(%s)", varname)
-		return
+		x.linef("} else if !z.EncBasicHandle().TimeNotBuiltin { r.EncodeTime(%s)", varname)
+		// return
 	}
 	if t == rawTyp {
 		x.linef("} else { z.EncRaw(%s)", varname)
@@ -1332,8 +1332,8 @@ func (x *genRunner) dec(varname string, t reflect.Type, isptr bool) {
 		addrPfx = "&"
 	}
 	if t == timeTyp {
-		x.linef("} else { %s%v = r.DecodeTime()", ptrPfx, varname)
-		return
+		x.linef("} else if !z.DecBasicHandle().TimeNotBuiltin { %s%v = r.DecodeTime()", ptrPfx, varname)
+		// return
 	}
 	if t == rawTyp {
 		x.linef("} else { %s%v = z.DecRaw()", ptrPfx, varname)

+ 13 - 1
codec/helper.go

@@ -495,6 +495,18 @@ type BasicHandle struct {
 
 	RPCOptions
 
+	// TimeNotBuiltin configures whether time.Time should be treated as a builtin type.
+	//
+	// All Handlers should know how to encode/decode time.Time as part of the core
+	// format specification, or as a standard extension defined by the format.
+	//
+	// However, users can elect to handle time.Time as a custom extension, or via the
+	// standard library's encoding.Binary(M|Unm)arshaler or Text(M|Unm)arshaler interface.
+	// To elect this behavior, users can set TimeNotBuiltin=true.
+	// Note: Setting TimeNotBuiltin=true can be used to enable the legacy behavior
+	// (for Cbor and Msgpack), where time.Time was not a builtin supported type.
+	TimeNotBuiltin bool
+
 	// ---- cache line
 
 	DecodeOptions
@@ -1763,7 +1775,7 @@ func (c *codecFner) get(rt reflect.Type, checkFastpath, checkCodecSelfer bool) (
 		fi.addrF = true
 		fi.addrD = ti.csp
 		fi.addrE = ti.csp
-	} else if rtid == timeTypId {
+	} else if rtid == timeTypId && !c.h.TimeNotBuiltin {
 		fn.fe = (*Encoder).kTime
 		fn.fd = (*Decoder).kTime
 	} else if rtid == rawTypId {