mirror of
https://github.com/kubernetes-sigs/prometheus-adapter.git
synced 2026-04-07 02:07:58 +00:00
Add vendor folder to git
This commit is contained in:
parent
66cf5eaafb
commit
183585f56f
6916 changed files with 2629581 additions and 1 deletions
385
vendor/github.com/mailru/easyjson/gen/decoder.go
generated
vendored
Normal file
385
vendor/github.com/mailru/easyjson/gen/decoder.go
generated
vendored
Normal file
|
|
@ -0,0 +1,385 @@
|
|||
package gen
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/mailru/easyjson"
|
||||
)
|
||||
|
||||
// Target this byte size for initial slice allocation to reduce garbage collection.
|
||||
const minSliceBytes = 64
|
||||
|
||||
func (g *Generator) getDecoderName(t reflect.Type) string {
|
||||
return g.functionName("decode", t)
|
||||
}
|
||||
|
||||
var primitiveDecoders = map[reflect.Kind]string{
|
||||
reflect.String: "in.String()",
|
||||
reflect.Bool: "in.Bool()",
|
||||
reflect.Int: "in.Int()",
|
||||
reflect.Int8: "in.Int8()",
|
||||
reflect.Int16: "in.Int16()",
|
||||
reflect.Int32: "in.Int32()",
|
||||
reflect.Int64: "in.Int64()",
|
||||
reflect.Uint: "in.Uint()",
|
||||
reflect.Uint8: "in.Uint8()",
|
||||
reflect.Uint16: "in.Uint16()",
|
||||
reflect.Uint32: "in.Uint32()",
|
||||
reflect.Uint64: "in.Uint64()",
|
||||
reflect.Float32: "in.Float32()",
|
||||
reflect.Float64: "in.Float64()",
|
||||
}
|
||||
|
||||
var primitiveStringDecoders = map[reflect.Kind]string{
|
||||
reflect.Int: "in.IntStr()",
|
||||
reflect.Int8: "in.Int8Str()",
|
||||
reflect.Int16: "in.Int16Str()",
|
||||
reflect.Int32: "in.Int32Str()",
|
||||
reflect.Int64: "in.Int64Str()",
|
||||
reflect.Uint: "in.UintStr()",
|
||||
reflect.Uint8: "in.Uint8Str()",
|
||||
reflect.Uint16: "in.Uint16Str()",
|
||||
reflect.Uint32: "in.Uint32Str()",
|
||||
reflect.Uint64: "in.Uint64Str()",
|
||||
}
|
||||
|
||||
// genTypeDecoder generates decoding code for the type t, but uses unmarshaler interface if implemented by t.
|
||||
func (g *Generator) genTypeDecoder(t reflect.Type, out string, tags fieldTags, indent int) error {
|
||||
ws := strings.Repeat(" ", indent)
|
||||
|
||||
unmarshalerIface := reflect.TypeOf((*easyjson.Unmarshaler)(nil)).Elem()
|
||||
if reflect.PtrTo(t).Implements(unmarshalerIface) {
|
||||
fmt.Fprintln(g.out, ws+"("+out+").UnmarshalEasyJSON(in)")
|
||||
return nil
|
||||
}
|
||||
|
||||
unmarshalerIface = reflect.TypeOf((*json.Unmarshaler)(nil)).Elem()
|
||||
if reflect.PtrTo(t).Implements(unmarshalerIface) {
|
||||
fmt.Fprintln(g.out, ws+"if data := in.Raw(); in.Ok() {")
|
||||
fmt.Fprintln(g.out, ws+" in.AddError( ("+out+").UnmarshalJSON(data) )")
|
||||
fmt.Fprintln(g.out, ws+"}")
|
||||
return nil
|
||||
}
|
||||
|
||||
err := g.genTypeDecoderNoCheck(t, out, tags, indent)
|
||||
return err
|
||||
}
|
||||
|
||||
// genTypeDecoderNoCheck generates decoding code for the type t.
|
||||
func (g *Generator) genTypeDecoderNoCheck(t reflect.Type, out string, tags fieldTags, indent int) error {
|
||||
ws := strings.Repeat(" ", indent)
|
||||
// Check whether type is primitive, needs to be done after interface check.
|
||||
if dec := primitiveStringDecoders[t.Kind()]; dec != "" && tags.asString {
|
||||
fmt.Fprintln(g.out, ws+out+" = "+g.getType(t)+"("+dec+")")
|
||||
return nil
|
||||
} else if dec := primitiveDecoders[t.Kind()]; dec != "" {
|
||||
fmt.Fprintln(g.out, ws+out+" = "+g.getType(t)+"("+dec+")")
|
||||
return nil
|
||||
}
|
||||
|
||||
switch t.Kind() {
|
||||
case reflect.Slice:
|
||||
tmpVar := g.uniqueVarName()
|
||||
elem := t.Elem()
|
||||
|
||||
capacity := minSliceBytes / elem.Size()
|
||||
if capacity == 0 {
|
||||
capacity = 1
|
||||
}
|
||||
|
||||
fmt.Fprintln(g.out, ws+"in.Delim('[')")
|
||||
fmt.Fprintln(g.out, ws+"if !in.IsDelim(']') {")
|
||||
fmt.Fprintln(g.out, ws+" "+out+" = make("+g.getType(t)+", 0, "+fmt.Sprint(capacity)+")")
|
||||
fmt.Fprintln(g.out, ws+"} else {")
|
||||
fmt.Fprintln(g.out, ws+" "+out+" = nil")
|
||||
fmt.Fprintln(g.out, ws+"}")
|
||||
fmt.Fprintln(g.out, ws+"for !in.IsDelim(']') {")
|
||||
fmt.Fprintln(g.out, ws+" var "+tmpVar+" "+g.getType(elem))
|
||||
|
||||
g.genTypeDecoder(elem, tmpVar, tags, indent+1)
|
||||
|
||||
fmt.Fprintln(g.out, ws+" "+out+" = append("+out+", "+tmpVar+")")
|
||||
fmt.Fprintln(g.out, ws+" in.WantComma()")
|
||||
fmt.Fprintln(g.out, ws+"}")
|
||||
fmt.Fprintln(g.out, ws+"in.Delim(']')")
|
||||
|
||||
case reflect.Struct:
|
||||
dec := g.getDecoderName(t)
|
||||
g.addType(t)
|
||||
|
||||
fmt.Fprintln(g.out, ws+dec+"(in, &"+out+")")
|
||||
|
||||
case reflect.Ptr:
|
||||
fmt.Fprintln(g.out, ws+"if in.IsNull() {")
|
||||
fmt.Fprintln(g.out, ws+" in.Skip()")
|
||||
fmt.Fprintln(g.out, ws+" "+out+" = nil")
|
||||
fmt.Fprintln(g.out, ws+"} else {")
|
||||
fmt.Fprintln(g.out, ws+" "+out+" = new("+g.getType(t.Elem())+")")
|
||||
|
||||
g.genTypeDecoder(t.Elem(), "*"+out, tags, indent+1)
|
||||
|
||||
fmt.Fprintln(g.out, ws+"}")
|
||||
|
||||
case reflect.Map:
|
||||
key := t.Key()
|
||||
if key.Kind() != reflect.String {
|
||||
return fmt.Errorf("map type %v not supported: only string keys are allowed", key)
|
||||
}
|
||||
elem := t.Elem()
|
||||
tmpVar := g.uniqueVarName()
|
||||
|
||||
fmt.Fprintln(g.out, ws+"if in.IsNull() {")
|
||||
fmt.Fprintln(g.out, ws+" in.Skip()")
|
||||
fmt.Fprintln(g.out, ws+"} else {")
|
||||
fmt.Fprintln(g.out, ws+" in.Delim('{')")
|
||||
fmt.Fprintln(g.out, ws+" if !in.IsDelim('}') {")
|
||||
fmt.Fprintln(g.out, ws+" "+out+" = make("+g.getType(t)+")")
|
||||
fmt.Fprintln(g.out, ws+" } else {")
|
||||
fmt.Fprintln(g.out, ws+" "+out+" = nil")
|
||||
fmt.Fprintln(g.out, ws+" }")
|
||||
|
||||
fmt.Fprintln(g.out, ws+" for !in.IsDelim('}') {")
|
||||
fmt.Fprintln(g.out, ws+" key := "+g.getType(t.Key())+"(in.String())")
|
||||
fmt.Fprintln(g.out, ws+" in.WantColon()")
|
||||
fmt.Fprintln(g.out, ws+" var "+tmpVar+" "+g.getType(elem))
|
||||
|
||||
g.genTypeDecoder(elem, tmpVar, tags, indent+2)
|
||||
|
||||
fmt.Fprintln(g.out, ws+" ("+out+")[key] = "+tmpVar)
|
||||
fmt.Fprintln(g.out, ws+" in.WantComma()")
|
||||
fmt.Fprintln(g.out, ws+" }")
|
||||
fmt.Fprintln(g.out, ws+" in.Delim('}')")
|
||||
fmt.Fprintln(g.out, ws+"}")
|
||||
|
||||
case reflect.Interface:
|
||||
if t.NumMethod() != 0 {
|
||||
return fmt.Errorf("interface type %v not supported: only interface{} is allowed", t)
|
||||
}
|
||||
fmt.Fprintln(g.out, ws+out+" = in.Interface()")
|
||||
|
||||
default:
|
||||
return fmt.Errorf("don't know how to decode %v", t)
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func (g *Generator) genStructFieldDecoder(t reflect.Type, f reflect.StructField) error {
|
||||
jsonName := g.fieldNamer.GetJSONFieldName(t, f)
|
||||
tags := parseFieldTags(f)
|
||||
|
||||
if tags.omit {
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Fprintf(g.out, " case %q:\n", jsonName)
|
||||
if err := g.genTypeDecoder(f.Type, "out."+f.Name, tags, 3); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if tags.required {
|
||||
fmt.Fprintf(g.out, "%sSet = true\n", f.Name)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *Generator) genRequiredFieldSet(t reflect.Type, f reflect.StructField) {
|
||||
tags := parseFieldTags(f)
|
||||
|
||||
if !tags.required {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Fprintf(g.out, "var %sSet bool\n", f.Name)
|
||||
}
|
||||
|
||||
func (g *Generator) genRequiredFieldCheck(t reflect.Type, f reflect.StructField) {
|
||||
jsonName := g.fieldNamer.GetJSONFieldName(t, f)
|
||||
tags := parseFieldTags(f)
|
||||
|
||||
if !tags.required {
|
||||
return
|
||||
}
|
||||
|
||||
g.imports["fmt"] = "fmt"
|
||||
|
||||
fmt.Fprintf(g.out, "if !%sSet {\n", f.Name)
|
||||
fmt.Fprintf(g.out, " in.AddError(fmt.Errorf(\"key '%s' is required\"))\n", jsonName)
|
||||
fmt.Fprintf(g.out, "}\n")
|
||||
}
|
||||
|
||||
func mergeStructFields(fields1, fields2 []reflect.StructField) (fields []reflect.StructField) {
|
||||
used := map[string]bool{}
|
||||
for _, f := range fields2 {
|
||||
used[f.Name] = true
|
||||
fields = append(fields, f)
|
||||
}
|
||||
|
||||
for _, f := range fields1 {
|
||||
if !used[f.Name] {
|
||||
fields = append(fields, f)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getStructFields(t reflect.Type) ([]reflect.StructField, error) {
|
||||
if t.Kind() != reflect.Struct {
|
||||
return nil, fmt.Errorf("got %v; expected a struct", t)
|
||||
}
|
||||
|
||||
var efields []reflect.StructField
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
f := t.Field(i)
|
||||
if !f.Anonymous {
|
||||
continue
|
||||
}
|
||||
|
||||
t1 := f.Type
|
||||
if t1.Kind() == reflect.Ptr {
|
||||
t1 = t1.Elem()
|
||||
}
|
||||
|
||||
fs, err := getStructFields(t1)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error processing embedded field: %v", err)
|
||||
}
|
||||
efields = mergeStructFields(efields, fs)
|
||||
}
|
||||
|
||||
var fields []reflect.StructField
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
f := t.Field(i)
|
||||
if f.Anonymous {
|
||||
continue
|
||||
}
|
||||
|
||||
c := []rune(f.Name)[0]
|
||||
if unicode.IsUpper(c) {
|
||||
fields = append(fields, f)
|
||||
}
|
||||
}
|
||||
return mergeStructFields(efields, fields), nil
|
||||
}
|
||||
|
||||
func (g *Generator) genDecoder(t reflect.Type) error {
|
||||
switch t.Kind() {
|
||||
case reflect.Slice:
|
||||
return g.genSliceDecoder(t)
|
||||
default:
|
||||
return g.genStructDecoder(t)
|
||||
}
|
||||
}
|
||||
|
||||
func (g *Generator) genSliceDecoder(t reflect.Type) error {
|
||||
if t.Kind() != reflect.Slice {
|
||||
return fmt.Errorf("cannot generate encoder/decoder for %v, not a slice type", t)
|
||||
}
|
||||
|
||||
fname := g.getDecoderName(t)
|
||||
typ := g.getType(t)
|
||||
|
||||
fmt.Fprintln(g.out, "func "+fname+"(in *jlexer.Lexer, out *"+typ+") {")
|
||||
err := g.genTypeDecoderNoCheck(t, "*out", fieldTags{}, 1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintln(g.out, "}")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *Generator) genStructDecoder(t reflect.Type) error {
|
||||
if t.Kind() != reflect.Struct {
|
||||
return fmt.Errorf("cannot generate encoder/decoder for %v, not a struct type", t)
|
||||
}
|
||||
|
||||
fname := g.getDecoderName(t)
|
||||
typ := g.getType(t)
|
||||
|
||||
fmt.Fprintln(g.out, "func "+fname+"(in *jlexer.Lexer, out *"+typ+") {")
|
||||
fmt.Fprintln(g.out, " if in.IsNull() {")
|
||||
fmt.Fprintln(g.out, " in.Skip()")
|
||||
fmt.Fprintln(g.out, " return")
|
||||
fmt.Fprintln(g.out, " }")
|
||||
|
||||
// Init embedded pointer fields.
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
f := t.Field(i)
|
||||
if !f.Anonymous || f.Type.Kind() != reflect.Ptr {
|
||||
continue
|
||||
}
|
||||
fmt.Fprintln(g.out, " out."+f.Name+" = new("+g.getType(f.Type.Elem())+")")
|
||||
}
|
||||
|
||||
fs, err := getStructFields(t)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot generate decoder for %v: %v", t, err)
|
||||
}
|
||||
|
||||
for _, f := range fs {
|
||||
g.genRequiredFieldSet(t, f)
|
||||
}
|
||||
|
||||
fmt.Fprintln(g.out, " in.Delim('{')")
|
||||
fmt.Fprintln(g.out, " for !in.IsDelim('}') {")
|
||||
fmt.Fprintln(g.out, " key := in.UnsafeString()")
|
||||
fmt.Fprintln(g.out, " in.WantColon()")
|
||||
fmt.Fprintln(g.out, " if in.IsNull() {")
|
||||
fmt.Fprintln(g.out, " in.Skip()")
|
||||
fmt.Fprintln(g.out, " in.WantComma()")
|
||||
fmt.Fprintln(g.out, " continue")
|
||||
fmt.Fprintln(g.out, " }")
|
||||
|
||||
fmt.Fprintln(g.out, " switch key {")
|
||||
for _, f := range fs {
|
||||
if err := g.genStructFieldDecoder(t, f); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Fprintln(g.out, " default:")
|
||||
fmt.Fprintln(g.out, " in.SkipRecursive()")
|
||||
fmt.Fprintln(g.out, " }")
|
||||
fmt.Fprintln(g.out, " in.WantComma()")
|
||||
fmt.Fprintln(g.out, " }")
|
||||
fmt.Fprintln(g.out, " in.Delim('}')")
|
||||
|
||||
for _, f := range fs {
|
||||
g.genRequiredFieldCheck(t, f)
|
||||
}
|
||||
|
||||
fmt.Fprintln(g.out, "}")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *Generator) genStructUnmarshaller(t reflect.Type) error {
|
||||
if t.Kind() != reflect.Struct && t.Kind() != reflect.Slice {
|
||||
return fmt.Errorf("cannot generate encoder/decoder for %v, not a struct/slice type", t)
|
||||
}
|
||||
|
||||
fname := g.getDecoderName(t)
|
||||
typ := g.getType(t)
|
||||
|
||||
if !g.noStdMarshalers {
|
||||
fmt.Fprintln(g.out, "// UnmarshalJSON supports json.Unmarshaler interface")
|
||||
fmt.Fprintln(g.out, "func (v *"+typ+") UnmarshalJSON(data []byte) error {")
|
||||
fmt.Fprintln(g.out, " r := jlexer.Lexer{Data: data}")
|
||||
fmt.Fprintln(g.out, " "+fname+"(&r, v)")
|
||||
fmt.Fprintln(g.out, " return r.Error()")
|
||||
fmt.Fprintln(g.out, "}")
|
||||
}
|
||||
|
||||
fmt.Fprintln(g.out, "// UnmarshalEasyJSON supports easyjson.Unmarshaler interface")
|
||||
fmt.Fprintln(g.out, "func (v *"+typ+") UnmarshalEasyJSON(l *jlexer.Lexer) {")
|
||||
fmt.Fprintln(g.out, " "+fname+"(l, v)")
|
||||
fmt.Fprintln(g.out, "}")
|
||||
|
||||
return nil
|
||||
}
|
||||
313
vendor/github.com/mailru/easyjson/gen/encoder.go
generated
vendored
Normal file
313
vendor/github.com/mailru/easyjson/gen/encoder.go
generated
vendored
Normal file
|
|
@ -0,0 +1,313 @@
|
|||
package gen
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/mailru/easyjson"
|
||||
)
|
||||
|
||||
func (g *Generator) getEncoderName(t reflect.Type) string {
|
||||
return g.functionName("encode", t)
|
||||
}
|
||||
|
||||
var primitiveEncoders = map[reflect.Kind]string{
|
||||
reflect.String: "out.String(string(%v))",
|
||||
reflect.Bool: "out.Bool(bool(%v))",
|
||||
reflect.Int: "out.Int(int(%v))",
|
||||
reflect.Int8: "out.Int8(int8(%v))",
|
||||
reflect.Int16: "out.Int16(int16(%v))",
|
||||
reflect.Int32: "out.Int32(int32(%v))",
|
||||
reflect.Int64: "out.Int64(int64(%v))",
|
||||
reflect.Uint: "out.Uint(uint(%v))",
|
||||
reflect.Uint8: "out.Uint8(uint8(%v))",
|
||||
reflect.Uint16: "out.Uint16(uint16(%v))",
|
||||
reflect.Uint32: "out.Uint32(uint32(%v))",
|
||||
reflect.Uint64: "out.Uint64(uint64(%v))",
|
||||
reflect.Float32: "out.Float32(float32(%v))",
|
||||
reflect.Float64: "out.Float64(float64(%v))",
|
||||
}
|
||||
|
||||
var primitiveStringEncoders = map[reflect.Kind]string{
|
||||
reflect.Int: "out.IntStr(int(%v))",
|
||||
reflect.Int8: "out.Int8Str(int8(%v))",
|
||||
reflect.Int16: "out.Int16Str(int16(%v))",
|
||||
reflect.Int32: "out.Int32Str(int32(%v))",
|
||||
reflect.Int64: "out.Int64Str(int64(%v))",
|
||||
reflect.Uint: "out.UintStr(uint(%v))",
|
||||
reflect.Uint8: "out.Uint8Str(uint8(%v))",
|
||||
reflect.Uint16: "out.Uint16Str(uint16(%v))",
|
||||
reflect.Uint32: "out.Uint32Str(uint32(%v))",
|
||||
reflect.Uint64: "out.Uint64Str(uint64(%v))",
|
||||
}
|
||||
|
||||
// fieldTags contains parsed version of json struct field tags.
|
||||
type fieldTags struct {
|
||||
name string
|
||||
|
||||
omit bool
|
||||
omitEmpty bool
|
||||
noOmitEmpty bool
|
||||
asString bool
|
||||
required bool
|
||||
}
|
||||
|
||||
// parseFieldTags parses the json field tag into a structure.
|
||||
func parseFieldTags(f reflect.StructField) fieldTags {
|
||||
var ret fieldTags
|
||||
|
||||
for i, s := range strings.Split(f.Tag.Get("json"), ",") {
|
||||
switch {
|
||||
case i == 0 && s == "-":
|
||||
ret.omit = true
|
||||
case i == 0:
|
||||
ret.name = s
|
||||
case s == "omitempty":
|
||||
ret.omitEmpty = true
|
||||
case s == "!omitempty":
|
||||
ret.noOmitEmpty = true
|
||||
case s == "string":
|
||||
ret.asString = true
|
||||
case s == "required":
|
||||
ret.required = true
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
// genTypeEncoder generates code that encodes in of type t into the writer, but uses marshaler interface if implemented by t.
|
||||
func (g *Generator) genTypeEncoder(t reflect.Type, in string, tags fieldTags, indent int) error {
|
||||
ws := strings.Repeat(" ", indent)
|
||||
|
||||
marshalerIface := reflect.TypeOf((*easyjson.Marshaler)(nil)).Elem()
|
||||
if reflect.PtrTo(t).Implements(marshalerIface) {
|
||||
fmt.Fprintln(g.out, ws+"("+in+").MarshalEasyJSON(out)")
|
||||
return nil
|
||||
}
|
||||
|
||||
marshalerIface = reflect.TypeOf((*json.Marshaler)(nil)).Elem()
|
||||
if reflect.PtrTo(t).Implements(marshalerIface) {
|
||||
fmt.Fprintln(g.out, ws+"out.Raw( ("+in+").MarshalJSON() )")
|
||||
return nil
|
||||
}
|
||||
|
||||
err := g.genTypeEncoderNoCheck(t, in, tags, indent)
|
||||
return err
|
||||
}
|
||||
|
||||
// genTypeEncoderNoCheck generates code that encodes in of type t into the writer.
|
||||
func (g *Generator) genTypeEncoderNoCheck(t reflect.Type, in string, tags fieldTags, indent int) error {
|
||||
ws := strings.Repeat(" ", indent)
|
||||
|
||||
// Check whether type is primitive, needs to be done after interface check.
|
||||
if enc := primitiveStringEncoders[t.Kind()]; enc != "" && tags.asString {
|
||||
fmt.Fprintf(g.out, ws+enc+"\n", in)
|
||||
return nil
|
||||
} else if enc := primitiveEncoders[t.Kind()]; enc != "" {
|
||||
fmt.Fprintf(g.out, ws+enc+"\n", in)
|
||||
return nil
|
||||
}
|
||||
|
||||
switch t.Kind() {
|
||||
case reflect.Slice:
|
||||
elem := t.Elem()
|
||||
iVar := g.uniqueVarName()
|
||||
vVar := g.uniqueVarName()
|
||||
|
||||
fmt.Fprintln(g.out, ws+"out.RawByte('[')")
|
||||
fmt.Fprintln(g.out, ws+"for "+iVar+", "+vVar+" := range "+in+" {")
|
||||
fmt.Fprintln(g.out, ws+" if "+iVar+" > 0 {")
|
||||
fmt.Fprintln(g.out, ws+" out.RawByte(',')")
|
||||
fmt.Fprintln(g.out, ws+" }")
|
||||
|
||||
g.genTypeEncoder(elem, vVar, tags, indent+1)
|
||||
|
||||
fmt.Fprintln(g.out, ws+"}")
|
||||
fmt.Fprintln(g.out, ws+"out.RawByte(']')")
|
||||
|
||||
case reflect.Struct:
|
||||
enc := g.getEncoderName(t)
|
||||
g.addType(t)
|
||||
|
||||
fmt.Fprintln(g.out, ws+enc+"(out, "+in+")")
|
||||
|
||||
case reflect.Ptr:
|
||||
fmt.Fprintln(g.out, ws+"if "+in+" == nil {")
|
||||
fmt.Fprintln(g.out, ws+` out.RawString("null")`)
|
||||
fmt.Fprintln(g.out, ws+"} else {")
|
||||
|
||||
g.genTypeEncoder(t.Elem(), "*"+in, tags, indent+1)
|
||||
|
||||
fmt.Fprintln(g.out, ws+"}")
|
||||
|
||||
case reflect.Map:
|
||||
key := t.Key()
|
||||
if key.Kind() != reflect.String {
|
||||
return fmt.Errorf("map type %v not supported: only string keys are allowed", key)
|
||||
}
|
||||
tmpVar := g.uniqueVarName()
|
||||
|
||||
fmt.Fprintln(g.out, ws+"if "+in+" == nil {")
|
||||
fmt.Fprintln(g.out, ws+" out.RawString(`null`)")
|
||||
fmt.Fprintln(g.out, ws+"} else {")
|
||||
fmt.Fprintln(g.out, ws+" out.RawByte('{')")
|
||||
fmt.Fprintln(g.out, ws+" "+tmpVar+"First := true")
|
||||
fmt.Fprintln(g.out, ws+" for "+tmpVar+"Name, "+tmpVar+"Value := range "+in+" {")
|
||||
fmt.Fprintln(g.out, ws+" if !"+tmpVar+"First { out.RawByte(',') }")
|
||||
fmt.Fprintln(g.out, ws+" "+tmpVar+"First = false")
|
||||
fmt.Fprintln(g.out, ws+" out.String(string("+tmpVar+"Name))")
|
||||
fmt.Fprintln(g.out, ws+" out.RawByte(':')")
|
||||
|
||||
g.genTypeEncoder(t.Elem(), tmpVar+"Value", tags, indent+2)
|
||||
|
||||
fmt.Fprintln(g.out, ws+" }")
|
||||
fmt.Fprintln(g.out, ws+" out.RawByte('}')")
|
||||
fmt.Fprintln(g.out, ws+"}")
|
||||
|
||||
case reflect.Interface:
|
||||
if t.NumMethod() != 0 {
|
||||
return fmt.Errorf("interface type %v not supported: only interface{} is allowed", t)
|
||||
}
|
||||
fmt.Fprintln(g.out, ws+"out.Raw(json.Marshal("+in+"))")
|
||||
|
||||
default:
|
||||
return fmt.Errorf("don't know how to encode %v", t)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *Generator) notEmptyCheck(t reflect.Type, v string) string {
|
||||
optionalIface := reflect.TypeOf((*easyjson.Optional)(nil)).Elem()
|
||||
if reflect.PtrTo(t).Implements(optionalIface) {
|
||||
return "(" + v + ").IsDefined()"
|
||||
}
|
||||
|
||||
switch t.Kind() {
|
||||
case reflect.Slice, reflect.Map:
|
||||
return "len(" + v + ") != 0"
|
||||
case reflect.Interface, reflect.Ptr:
|
||||
return v + " != nil"
|
||||
case reflect.Bool:
|
||||
return v
|
||||
case reflect.String:
|
||||
return v + ` != ""`
|
||||
case reflect.Float32, reflect.Float64,
|
||||
reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
|
||||
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
|
||||
return v + " != 0"
|
||||
|
||||
default:
|
||||
return "true"
|
||||
}
|
||||
}
|
||||
|
||||
func (g *Generator) genStructFieldEncoder(t reflect.Type, f reflect.StructField) error {
|
||||
jsonName := g.fieldNamer.GetJSONFieldName(t, f)
|
||||
tags := parseFieldTags(f)
|
||||
|
||||
if tags.omit {
|
||||
return nil
|
||||
}
|
||||
if !tags.omitEmpty && !g.omitEmpty || tags.noOmitEmpty {
|
||||
fmt.Fprintln(g.out, " if !first { out.RawByte(',') }")
|
||||
fmt.Fprintln(g.out, " first = false")
|
||||
fmt.Fprintf(g.out, " out.RawString(%q)\n", strconv.Quote(jsonName)+":")
|
||||
return g.genTypeEncoder(f.Type, "in."+f.Name, tags, 1)
|
||||
}
|
||||
|
||||
fmt.Fprintln(g.out, " if", g.notEmptyCheck(f.Type, "in."+f.Name), "{")
|
||||
fmt.Fprintln(g.out, " if !first { out.RawByte(',') }")
|
||||
fmt.Fprintln(g.out, " first = false")
|
||||
|
||||
fmt.Fprintf(g.out, " out.RawString(%q)\n", strconv.Quote(jsonName)+":")
|
||||
if err := g.genTypeEncoder(f.Type, "in."+f.Name, tags, 2); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintln(g.out, " }")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *Generator) genEncoder(t reflect.Type) error {
|
||||
switch t.Kind() {
|
||||
case reflect.Slice:
|
||||
return g.genSliceEncoder(t)
|
||||
default:
|
||||
return g.genStructEncoder(t)
|
||||
}
|
||||
}
|
||||
|
||||
func (g *Generator) genSliceEncoder(t reflect.Type) error {
|
||||
if t.Kind() != reflect.Slice {
|
||||
return fmt.Errorf("cannot generate encoder/decoder for %v, not a slice type", t)
|
||||
}
|
||||
|
||||
fname := g.getEncoderName(t)
|
||||
typ := g.getType(t)
|
||||
|
||||
fmt.Fprintln(g.out, "func "+fname+"(out *jwriter.Writer, in "+typ+") {")
|
||||
err := g.genTypeEncoderNoCheck(t, "in", fieldTags{}, 1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintln(g.out, "}")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *Generator) genStructEncoder(t reflect.Type) error {
|
||||
if t.Kind() != reflect.Struct {
|
||||
return fmt.Errorf("cannot generate encoder/decoder for %v, not a struct type")
|
||||
}
|
||||
|
||||
fname := g.getEncoderName(t)
|
||||
typ := g.getType(t)
|
||||
|
||||
fmt.Fprintln(g.out, "func "+fname+"(out *jwriter.Writer, in "+typ+") {")
|
||||
fmt.Fprintln(g.out, " out.RawByte('{')")
|
||||
fmt.Fprintln(g.out, " first := true")
|
||||
fmt.Fprintln(g.out, " _ = first")
|
||||
|
||||
fs, err := getStructFields(t)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot generate encoder for %v: %v", t, err)
|
||||
}
|
||||
for _, f := range fs {
|
||||
if err := g.genStructFieldEncoder(t, f); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Fprintln(g.out, " out.RawByte('}')")
|
||||
fmt.Fprintln(g.out, "}")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *Generator) genStructMarshaller(t reflect.Type) error {
|
||||
if t.Kind() != reflect.Struct && t.Kind() != reflect.Slice {
|
||||
return fmt.Errorf("cannot generate encoder/decoder for %v, not a struct/slice type", t)
|
||||
}
|
||||
|
||||
fname := g.getEncoderName(t)
|
||||
typ := g.getType(t)
|
||||
|
||||
if !g.noStdMarshalers {
|
||||
fmt.Fprintln(g.out, "// MarshalJSON supports json.Marshaler interface")
|
||||
fmt.Fprintln(g.out, "func (v "+typ+") MarshalJSON() ([]byte, error) {")
|
||||
fmt.Fprintln(g.out, " w := jwriter.Writer{}")
|
||||
fmt.Fprintln(g.out, " "+fname+"(&w, v)")
|
||||
fmt.Fprintln(g.out, " return w.Buffer.BuildBytes(), w.Error")
|
||||
fmt.Fprintln(g.out, "}")
|
||||
}
|
||||
|
||||
fmt.Fprintln(g.out, "// MarshalEasyJSON supports easyjson.Marshaler interface")
|
||||
fmt.Fprintln(g.out, "func (v "+typ+") MarshalEasyJSON(w *jwriter.Writer) {")
|
||||
fmt.Fprintln(g.out, " "+fname+"(w, v)")
|
||||
fmt.Fprintln(g.out, "}")
|
||||
|
||||
return nil
|
||||
}
|
||||
395
vendor/github.com/mailru/easyjson/gen/generator.go
generated
vendored
Normal file
395
vendor/github.com/mailru/easyjson/gen/generator.go
generated
vendored
Normal file
|
|
@ -0,0 +1,395 @@
|
|||
package gen
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"hash/fnv"
|
||||
"io"
|
||||
"path"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
const pkgWriter = "github.com/mailru/easyjson/jwriter"
|
||||
const pkgLexer = "github.com/mailru/easyjson/jlexer"
|
||||
|
||||
// FieldNamer defines a policy for generating names for struct fields.
|
||||
type FieldNamer interface {
|
||||
GetJSONFieldName(t reflect.Type, f reflect.StructField) string
|
||||
}
|
||||
|
||||
// Generator generates the requested marshallers/unmarshallers.
|
||||
type Generator struct {
|
||||
out *bytes.Buffer
|
||||
|
||||
pkgName string
|
||||
pkgPath string
|
||||
buildTags string
|
||||
hashString string
|
||||
|
||||
varCounter int
|
||||
|
||||
noStdMarshalers bool
|
||||
omitEmpty bool
|
||||
fieldNamer FieldNamer
|
||||
|
||||
// package path to local alias map for tracking imports
|
||||
imports map[string]string
|
||||
|
||||
// types that marshallers were requested for by user
|
||||
marshallers map[reflect.Type]bool
|
||||
|
||||
// types that encoders were already generated for
|
||||
typesSeen map[reflect.Type]bool
|
||||
|
||||
// types that encoders were requested for (e.g. by encoders of other types)
|
||||
typesUnseen []reflect.Type
|
||||
|
||||
// function name to relevant type maps to track names of de-/encoders in
|
||||
// case of a name clash or unnamed structs
|
||||
functionNames map[string]reflect.Type
|
||||
}
|
||||
|
||||
// NewGenerator initializes and returns a Generator.
|
||||
func NewGenerator(filename string) *Generator {
|
||||
ret := &Generator{
|
||||
imports: map[string]string{
|
||||
pkgWriter: "jwriter",
|
||||
pkgLexer: "jlexer",
|
||||
"encoding/json": "json",
|
||||
},
|
||||
fieldNamer: DefaultFieldNamer{},
|
||||
marshallers: make(map[reflect.Type]bool),
|
||||
typesSeen: make(map[reflect.Type]bool),
|
||||
functionNames: make(map[string]reflect.Type),
|
||||
}
|
||||
|
||||
// Use a file-unique prefix on all auxiliary functions to avoid
|
||||
// name clashes.
|
||||
hash := fnv.New32()
|
||||
hash.Write([]byte(filename))
|
||||
ret.hashString = fmt.Sprintf("%x", hash.Sum32())
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
// SetPkg sets the name and path of output package.
|
||||
func (g *Generator) SetPkg(name, path string) {
|
||||
g.pkgName = name
|
||||
g.pkgPath = path
|
||||
}
|
||||
|
||||
// SetBuildTags sets build tags for the output file.
|
||||
func (g *Generator) SetBuildTags(tags string) {
|
||||
g.buildTags = tags
|
||||
}
|
||||
|
||||
// SetFieldNamer sets field naming strategy.
|
||||
func (g *Generator) SetFieldNamer(n FieldNamer) {
|
||||
g.fieldNamer = n
|
||||
}
|
||||
|
||||
// UseSnakeCase sets snake_case field naming strategy.
|
||||
func (g *Generator) UseSnakeCase() {
|
||||
g.fieldNamer = SnakeCaseFieldNamer{}
|
||||
}
|
||||
|
||||
// NoStdMarshalers instructs not to generate standard MarshalJSON/UnmarshalJSON
|
||||
// methods (only the custom interface).
|
||||
func (g *Generator) NoStdMarshalers() {
|
||||
g.noStdMarshalers = true
|
||||
}
|
||||
|
||||
// OmitEmpty triggers `json=",omitempty"` behaviour by default.
|
||||
func (g *Generator) OmitEmpty() {
|
||||
g.omitEmpty = true
|
||||
}
|
||||
|
||||
// addTypes requests to generate en-/decoding functions for the given type.
|
||||
func (g *Generator) addType(t reflect.Type) {
|
||||
if g.typesSeen[t] {
|
||||
return
|
||||
}
|
||||
for _, t1 := range g.typesUnseen {
|
||||
if t1 == t {
|
||||
return
|
||||
}
|
||||
}
|
||||
g.typesUnseen = append(g.typesUnseen, t)
|
||||
}
|
||||
|
||||
// Add requests to generate (un-)marshallers and en-/decoding functions for the type of given object.
|
||||
func (g *Generator) Add(obj interface{}) {
|
||||
t := reflect.TypeOf(obj)
|
||||
if t.Kind() == reflect.Ptr {
|
||||
t = t.Elem()
|
||||
}
|
||||
g.addType(t)
|
||||
g.marshallers[t] = true
|
||||
}
|
||||
|
||||
// printHeader prints package declaration and imports.
|
||||
func (g *Generator) printHeader() {
|
||||
if g.buildTags != "" {
|
||||
fmt.Println("// +build ", g.buildTags)
|
||||
fmt.Println()
|
||||
}
|
||||
fmt.Println("// AUTOGENERATED FILE: easyjson marshaller/unmarshallers.")
|
||||
fmt.Println()
|
||||
fmt.Println("package ", g.pkgName)
|
||||
fmt.Println()
|
||||
|
||||
byAlias := map[string]string{}
|
||||
var aliases []string
|
||||
for path, alias := range g.imports {
|
||||
aliases = append(aliases, alias)
|
||||
byAlias[alias] = path
|
||||
}
|
||||
|
||||
sort.Strings(aliases)
|
||||
fmt.Println("import (")
|
||||
for _, alias := range g.imports {
|
||||
fmt.Printf(" %s %q\n", alias, byAlias[alias])
|
||||
}
|
||||
|
||||
fmt.Println(")")
|
||||
fmt.Println("")
|
||||
fmt.Println("// suppress unused package warning")
|
||||
fmt.Println("var (")
|
||||
fmt.Println(" _ = json.RawMessage{}")
|
||||
fmt.Println(" _ = jlexer.Lexer{}")
|
||||
fmt.Println(" _ = jwriter.Writer{}")
|
||||
fmt.Println(")")
|
||||
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
// Run runs the generator and outputs generated code to out.
|
||||
func (g *Generator) Run(out io.Writer) error {
|
||||
g.out = &bytes.Buffer{}
|
||||
|
||||
for len(g.typesUnseen) > 0 {
|
||||
t := g.typesUnseen[len(g.typesUnseen)-1]
|
||||
g.typesUnseen = g.typesUnseen[:len(g.typesUnseen)-1]
|
||||
g.typesSeen[t] = true
|
||||
|
||||
if err := g.genDecoder(t); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.genEncoder(t); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !g.marshallers[t] {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := g.genStructMarshaller(t); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.genStructUnmarshaller(t); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
g.printHeader()
|
||||
_, err := out.Write(g.out.Bytes())
|
||||
return err
|
||||
}
|
||||
|
||||
// pkgAlias creates and returns and import alias for a given package.
|
||||
func (g *Generator) pkgAlias(pkgPath string) string {
|
||||
if alias := g.imports[pkgPath]; alias != "" {
|
||||
return alias
|
||||
}
|
||||
|
||||
for i := 0; ; i++ {
|
||||
alias := path.Base(pkgPath)
|
||||
if i > 0 {
|
||||
alias += fmt.Sprint(i)
|
||||
}
|
||||
|
||||
exists := false
|
||||
for _, v := range g.imports {
|
||||
if v == alias {
|
||||
exists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !exists {
|
||||
g.imports[pkgPath] = alias
|
||||
return alias
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// getType return the textual type name of given type that can be used in generated code.
|
||||
func (g *Generator) getType(t reflect.Type) string {
|
||||
if t.Name() == "" {
|
||||
switch t.Kind() {
|
||||
case reflect.Ptr:
|
||||
return "*" + g.getType(t.Elem())
|
||||
case reflect.Slice:
|
||||
return "[]" + g.getType(t.Elem())
|
||||
case reflect.Map:
|
||||
return "map[" + g.getType(t.Key()) + "]" + g.getType(t.Elem())
|
||||
}
|
||||
}
|
||||
|
||||
if t.Name() == "" || t.PkgPath() == "" {
|
||||
return t.String()
|
||||
} else if t.PkgPath() == g.pkgPath {
|
||||
return t.Name()
|
||||
}
|
||||
// TODO: unnamed structs.
|
||||
return g.pkgAlias(t.PkgPath()) + "." + t.Name()
|
||||
}
|
||||
|
||||
// uniqueVarName returns a file-unique name that can be used for generated variables.
|
||||
func (g *Generator) uniqueVarName() string {
|
||||
g.varCounter++
|
||||
return fmt.Sprint("v", g.varCounter)
|
||||
}
|
||||
|
||||
// safeName escapes unsafe characters in pkg/type name and returns a string that can be used
|
||||
// in encoder/decoder names for the type.
|
||||
func (g *Generator) safeName(t reflect.Type) string {
|
||||
name := t.PkgPath()
|
||||
if t.Name() == "" {
|
||||
name += "anonymous"
|
||||
} else {
|
||||
name += "." + t.Name()
|
||||
}
|
||||
|
||||
parts := []string{}
|
||||
part := []rune{}
|
||||
for _, c := range name {
|
||||
if unicode.IsLetter(c) || unicode.IsDigit(c) {
|
||||
part = append(part, c)
|
||||
} else if len(part) > 0 {
|
||||
parts = append(parts, string(part))
|
||||
part = []rune{}
|
||||
}
|
||||
}
|
||||
return joinFunctionNameParts(false, parts...)
|
||||
}
|
||||
|
||||
// functionName returns a function name for a given type with a given prefix. If a function
|
||||
// with this prefix already exists for a type, it is returned.
|
||||
//
|
||||
// Method is used to track encoder/decoder names for the type.
|
||||
func (g *Generator) functionName(prefix string, t reflect.Type) string {
|
||||
prefix = joinFunctionNameParts(true, "easyjson", g.hashString, prefix)
|
||||
name := joinFunctionNameParts(true, prefix, g.safeName(t))
|
||||
|
||||
// Most of the names will be unique, try a shortcut first.
|
||||
if e, ok := g.functionNames[name]; !ok || e == t {
|
||||
g.functionNames[name] = t
|
||||
return name
|
||||
}
|
||||
|
||||
// Search if the function already exists.
|
||||
for name1, t1 := range g.functionNames {
|
||||
if t1 == t && strings.HasPrefix(name1, prefix) {
|
||||
return name1
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new name in the case of a clash.
|
||||
for i := 1; ; i++ {
|
||||
nm := fmt.Sprint(name, i)
|
||||
if _, ok := g.functionNames[nm]; ok {
|
||||
continue
|
||||
}
|
||||
g.functionNames[nm] = t
|
||||
return nm
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultFieldsNamer implements trivial naming policy equivalent to encoding/json.
|
||||
type DefaultFieldNamer struct{}
|
||||
|
||||
func (DefaultFieldNamer) GetJSONFieldName(t reflect.Type, f reflect.StructField) string {
|
||||
jsonName := strings.Split(f.Tag.Get("json"), ",")[0]
|
||||
if jsonName != "" {
|
||||
return jsonName
|
||||
} else {
|
||||
return f.Name
|
||||
}
|
||||
}
|
||||
|
||||
// SnakeCaseFieldNamer implements CamelCase to snake_case conversion for fields names.
|
||||
type SnakeCaseFieldNamer struct{}
|
||||
|
||||
func camelToSnake(name string) string {
|
||||
var ret bytes.Buffer
|
||||
|
||||
multipleUpper := false
|
||||
var lastUpper rune
|
||||
var beforeUpper rune
|
||||
|
||||
for _, c := range name {
|
||||
// Non-lowercase character after uppercase is considered to be uppercase too.
|
||||
isUpper := (unicode.IsUpper(c) || (lastUpper != 0 && !unicode.IsLower(c)))
|
||||
|
||||
if lastUpper != 0 {
|
||||
// Output a delimiter if last character was either the first uppercase character
|
||||
// in a row, or the last one in a row (e.g. 'S' in "HTTPServer").
|
||||
// Do not output a delimiter at the beginning of the name.
|
||||
|
||||
firstInRow := !multipleUpper
|
||||
lastInRow := !isUpper
|
||||
|
||||
if ret.Len() > 0 && (firstInRow || lastInRow) && beforeUpper != '_' {
|
||||
ret.WriteByte('_')
|
||||
}
|
||||
ret.WriteRune(unicode.ToLower(lastUpper))
|
||||
}
|
||||
|
||||
// Buffer uppercase char, do not output it yet as a delimiter may be required if the
|
||||
// next character is lowercase.
|
||||
if isUpper {
|
||||
multipleUpper = (lastUpper != 0)
|
||||
lastUpper = c
|
||||
continue
|
||||
}
|
||||
|
||||
ret.WriteRune(c)
|
||||
lastUpper = 0
|
||||
beforeUpper = c
|
||||
multipleUpper = false
|
||||
}
|
||||
|
||||
if lastUpper != 0 {
|
||||
ret.WriteRune(unicode.ToLower(lastUpper))
|
||||
}
|
||||
return string(ret.Bytes())
|
||||
}
|
||||
|
||||
func (SnakeCaseFieldNamer) GetJSONFieldName(t reflect.Type, f reflect.StructField) string {
|
||||
jsonName := strings.Split(f.Tag.Get("json"), ",")[0]
|
||||
if jsonName != "" {
|
||||
return jsonName
|
||||
}
|
||||
|
||||
return camelToSnake(f.Name)
|
||||
}
|
||||
|
||||
func joinFunctionNameParts(keepFirst bool, parts ...string) string {
|
||||
buf := bytes.NewBufferString("")
|
||||
for i, part := range parts {
|
||||
if i == 0 && keepFirst {
|
||||
buf.WriteString(part)
|
||||
} else {
|
||||
if len(part) > 0 {
|
||||
buf.WriteString(strings.ToUpper(string(part[0])))
|
||||
}
|
||||
if len(part) > 1 {
|
||||
buf.WriteString(part[1:])
|
||||
}
|
||||
}
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
49
vendor/github.com/mailru/easyjson/gen/generator_test.go
generated
vendored
Normal file
49
vendor/github.com/mailru/easyjson/gen/generator_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
package gen
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCamelToSnake(t *testing.T) {
|
||||
for i, test := range []struct {
|
||||
In, Out string
|
||||
}{
|
||||
{"", ""},
|
||||
{"A", "a"},
|
||||
{"SimpleExample", "simple_example"},
|
||||
{"internalField", "internal_field"},
|
||||
|
||||
{"SomeHTTPStuff", "some_http_stuff"},
|
||||
{"WriteJSON", "write_json"},
|
||||
{"HTTP2Server", "http2_server"},
|
||||
{"Some_Mixed_Case", "some_mixed_case"},
|
||||
{"do_nothing", "do_nothing"},
|
||||
|
||||
{"JSONHTTPRPCServer", "jsonhttprpc_server"}, // nothing can be done here without a dictionary
|
||||
} {
|
||||
got := camelToSnake(test.In)
|
||||
if got != test.Out {
|
||||
t.Errorf("[%d] camelToSnake(%s) = %s; want %s", i, test.In, got, test.Out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestJoinFunctionNameParts(t *testing.T) {
|
||||
for i, test := range []struct {
|
||||
keepFirst bool
|
||||
parts []string
|
||||
out string
|
||||
}{
|
||||
{false, []string{}, ""},
|
||||
{false, []string{"a"}, "A"},
|
||||
{false, []string{"simple", "example"}, "SimpleExample"},
|
||||
{true, []string{"first", "example"}, "firstExample"},
|
||||
{false, []string{"some", "UPPER", "case"}, "SomeUPPERCase"},
|
||||
{false, []string{"number", "123"}, "Number123"},
|
||||
} {
|
||||
got := joinFunctionNameParts(test.keepFirst, test.parts...)
|
||||
if got != test.out {
|
||||
t.Errorf("[%d] joinFunctionNameParts(%v) = %s; want %s", i, test.parts, got, test.out)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue