Browse Source

codec: support 'json:' as fallback to 'codec:' in struct tag configuration.

When getting struct tag value, look for keys: codec, json (in that sequence).

Also, codecgen CLI will handle errors using fmt.Fprintf and os.Exit(1).
Ugorji Nwoke 11 years ago
parent
commit
f20364ed02
6 changed files with 25 additions and 16 deletions
  1. 1 0
      codec/0doc.go
  2. 1 0
      codec/README.md
  3. 4 2
      codec/codecgen/gen.go
  4. 0 1
      codec/decode.go
  5. 7 9
      codec/encode.go
  6. 12 4
      codec/helper.go

+ 1 - 0
codec/0doc.go

@@ -63,6 +63,7 @@ Rich Feature Set includes:
     User decides whether to return an error or silently skip data when keys or indexes
     User decides whether to return an error or silently skip data when keys or indexes
     in the data stream do not map to fields in the struct.
     in the data stream do not map to fields in the struct.
   - Encode/Decode from/to chan types (for iterative streaming support)
   - Encode/Decode from/to chan types (for iterative streaming support)
+  - Drop-in replacement for encoding/json. `json:` key in struct tag supported.
   - Provides a RPC Server and Client Codec for net/rpc communication protocol.
   - Provides a RPC Server and Client Codec for net/rpc communication protocol.
   - Handle unique idiosynchracies of codecs e.g. 
   - Handle unique idiosynchracies of codecs e.g. 
     - For messagepack, configure how ambiguities in handling raw bytes are resolved 
     - For messagepack, configure how ambiguities in handling raw bytes are resolved 

+ 1 - 0
codec/README.md

@@ -64,6 +64,7 @@ Rich Feature Set includes:
     User decides whether to return an error or silently skip data when keys or indexes
     User decides whether to return an error or silently skip data when keys or indexes
     in the data stream do not map to fields in the struct.
     in the data stream do not map to fields in the struct.
   - Encode/Decode from/to chan types (for iterative streaming support)
   - Encode/Decode from/to chan types (for iterative streaming support)
+  - Drop-in replacement for encoding/json. `json:` key in struct tag supported.
   - Provides a RPC Server and Client Codec for net/rpc communication protocol.
   - Provides a RPC Server and Client Codec for net/rpc communication protocol.
   - Handle unique idiosynchracies of codecs e.g. 
   - Handle unique idiosynchracies of codecs e.g. 
     - For messagepack, configure how ambiguities in handling raw bytes are resolved 
     - For messagepack, configure how ambiguities in handling raw bytes are resolved 

+ 4 - 2
codec/codecgen/gen.go

@@ -217,7 +217,9 @@ func main() {
 	u := flag.Bool("u", false, "Use unsafe, e.g. to avoid unnecessary allocation on []byte->string")
 	u := flag.Bool("u", false, "Use unsafe, e.g. to avoid unnecessary allocation on []byte->string")
 
 
 	flag.Parse()
 	flag.Parse()
-	if err := Generate(*o, *t, *c, *u, *rt, regexp.MustCompile(*r), !*x, flag.Args()...); err != nil {
-		panic(err)
+	if err := Generate(*o, *t, *c, *u, *rt,
+		regexp.MustCompile(*r), !*x, flag.Args()...); err != nil {
+		fmt.Fprintf(os.Stderr, "codecgen error: %v\n", err)
+		os.Exit(1)
 	}
 	}
 }
 }

+ 0 - 1
codec/decode.go

@@ -13,7 +13,6 @@ import (
 
 
 // Some tagging information for error messages.
 // Some tagging information for error messages.
 const (
 const (
-	msgTagDec             = "codec.decoder"
 	msgBadDesc            = "Unrecognized descriptor byte"
 	msgBadDesc            = "Unrecognized descriptor byte"
 	msgDecCannotExpandArr = "cannot expand go array from %v to stream length: %v"
 	msgDecCannotExpandArr = "cannot expand go array from %v to stream length: %v"
 )
 )

+ 7 - 9
codec/encode.go

@@ -13,10 +13,7 @@ import (
 )
 )
 
 
 const (
 const (
-	// Some tagging information for error messages.
-	msgTagEnc         = "codec.encoder"
 	defEncByteBufSize = 1 << 6 // 4:16, 6:64, 8:256, 10:1024
 	defEncByteBufSize = 1 << 6 // 4:16, 6:64, 8:256, 10:1024
-	// maxTimeSecs32 = math.MaxInt32 / 60 / 24 / 366
 )
 )
 
 
 // AsSymbolFlag defines what should be encoded as symbols.
 // AsSymbolFlag defines what should be encoded as symbols.
@@ -809,26 +806,26 @@ func NewEncoderBytes(out *[]byte, h Handle) *Encoder {
 	return e
 	return e
 }
 }
 
 
-// Encode writes an object into a stream in the codec format.
-//
-// Encoding can be configured via the "codec" struct tag for the fields.
+// Encode writes an object into a stream.
 //
 //
+// Encoding can be configured via the struct tag for the fields.
 // The "codec" key in struct field's tag value is the key name,
 // The "codec" key in struct field's tag value is the key name,
 // followed by an optional comma and options.
 // followed by an optional comma and options.
+// Note that the "json" key is used in the absence of the "codec" key.
 //
 //
 // To set an option on all fields (e.g. omitempty on all fields), you
 // To set an option on all fields (e.g. omitempty on all fields), you
 // can create a field called _struct, and set flags on it.
 // can create a field called _struct, and set flags on it.
 //
 //
 // Struct values "usually" encode as maps. Each exported struct field is encoded unless:
 // Struct values "usually" encode as maps. Each exported struct field is encoded unless:
-//    - the field's codec tag is "-", OR
-//    - the field is empty and its codec tag specifies the "omitempty" option.
+//    - the field's tag is "-", OR
+//    - the field is empty (empty or the zero value) and its tag specifies the "omitempty" option.
 //
 //
 // When encoding as a map, the first string in the tag (before the comma)
 // When encoding as a map, the first string in the tag (before the comma)
 // is the map key string to use when encoding.
 // is the map key string to use when encoding.
 //
 //
 // However, struct values may encode as arrays. This happens when:
 // However, struct values may encode as arrays. This happens when:
 //    - StructToArray Encode option is set, OR
 //    - StructToArray Encode option is set, OR
-//    - the codec tag on the _struct field sets the "toarray" option
+//    - the tag on the _struct field sets the "toarray" option
 //
 //
 // Values with types that implement MapBySlice are encoded as stream maps.
 // Values with types that implement MapBySlice are encoded as stream maps.
 //
 //
@@ -840,6 +837,7 @@ func NewEncoderBytes(out *[]byte, h Handle) *Encoder {
 //
 //
 // Examples:
 // Examples:
 //
 //
+//      // NOTE: 'json:' can be used as struct tag key, in place 'codec:' below.
 //      type MyStruct struct {
 //      type MyStruct struct {
 //          _struct bool    `codec:",omitempty"`   //set omitempty for every field
 //          _struct bool    `codec:",omitempty"`   //set omitempty for every field
 //          Field1 string   `codec:"-"`            //skip this field
 //          Field1 string   `codec:"-"`            //skip this field

+ 12 - 4
codec/helper.go

@@ -116,8 +116,6 @@ import (
 )
 )
 
 
 const (
 const (
-	structTagName = "codec"
-
 	scratchByteArrayLen = 32
 	scratchByteArrayLen = 32
 
 
 	// Support encoding.(Binary|Text)(Unm|M)arshaler.
 	// Support encoding.(Binary|Text)(Unm|M)arshaler.
@@ -622,6 +620,16 @@ func (ti *typeInfo) indexForEncName(name string) int {
 	return -1
 	return -1
 }
 }
 
 
+func getStructTag(t reflect.StructTag) (s string) {
+	// check for tags: codec, json, in that order.
+	// this allows seamless support for many configured structs.
+	s = t.Get("codec")
+	if s == "" {
+		s = t.Get("json")
+	}
+	return
+}
+
 func getTypeInfo(rtid uintptr, rt reflect.Type) (pti *typeInfo) {
 func getTypeInfo(rtid uintptr, rt reflect.Type) (pti *typeInfo) {
 	var ok bool
 	var ok bool
 	cachedTypeInfoMutex.RLock()
 	cachedTypeInfoMutex.RLock()
@@ -679,7 +687,7 @@ func getTypeInfo(rtid uintptr, rt reflect.Type) (pti *typeInfo) {
 	if rt.Kind() == reflect.Struct {
 	if rt.Kind() == reflect.Struct {
 		var siInfo *structFieldInfo
 		var siInfo *structFieldInfo
 		if f, ok := rt.FieldByName(structInfoFieldName); ok {
 		if f, ok := rt.FieldByName(structInfoFieldName); ok {
-			siInfo = parseStructFieldInfo(structInfoFieldName, f.Tag.Get(structTagName))
+			siInfo = parseStructFieldInfo(structInfoFieldName, getStructTag(f.Tag))
 			ti.toArray = siInfo.toArray
 			ti.toArray = siInfo.toArray
 		}
 		}
 		sfip := make([]*structFieldInfo, 0, rt.NumField())
 		sfip := make([]*structFieldInfo, 0, rt.NumField())
@@ -705,7 +713,7 @@ func rgetTypeInfo(rt reflect.Type, indexstack []int, fnameToHastag map[string]bo
 		if tk := f.Type.Kind(); tk == reflect.Func {
 		if tk := f.Type.Kind(); tk == reflect.Func {
 			continue
 			continue
 		}
 		}
-		stag := f.Tag.Get(structTagName)
+		stag := getStructTag(f.Tag)
 		if stag == "-" {
 		if stag == "-" {
 			continue
 			continue
 		}
 		}