mirror of
https://github.com/golang/go
synced 2024-11-25 07:37:57 -07:00
json: allow using '$' and '-' as the struct field's tag
R=adg, rsc, bradfitz, mattn.jp, gustavo CC=golang-dev https://golang.org/cl/4625081
This commit is contained in:
parent
125e8277d5
commit
689a2ec8c3
@ -40,13 +40,6 @@ var (
|
|||||||
umtrue = unmarshaler{true}
|
umtrue = unmarshaler{true}
|
||||||
)
|
)
|
||||||
|
|
||||||
type badTag struct {
|
|
||||||
X string
|
|
||||||
Y string `json:"y"`
|
|
||||||
Z string `x:"@#*%(#@"`
|
|
||||||
W string `json:"@#$@#$"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type unmarshalTest struct {
|
type unmarshalTest struct {
|
||||||
in string
|
in string
|
||||||
ptr interface{}
|
ptr interface{}
|
||||||
@ -68,9 +61,6 @@ var unmarshalTests = []unmarshalTest{
|
|||||||
{`{"X": [1,2,3], "Y": 4}`, new(T), T{Y: 4}, &UnmarshalTypeError{"array", reflect.TypeOf("")}},
|
{`{"X": [1,2,3], "Y": 4}`, new(T), T{Y: 4}, &UnmarshalTypeError{"array", reflect.TypeOf("")}},
|
||||||
{`{"x": 1}`, new(tx), tx{}, &UnmarshalFieldError{"x", txType, txType.Field(0)}},
|
{`{"x": 1}`, new(tx), tx{}, &UnmarshalFieldError{"x", txType, txType.Field(0)}},
|
||||||
|
|
||||||
// skip invalid tags
|
|
||||||
{`{"X":"a", "y":"b", "Z":"c", "W":"d"}`, new(badTag), badTag{"a", "b", "c", "d"}, nil},
|
|
||||||
|
|
||||||
// syntax errors
|
// syntax errors
|
||||||
{`{"X": "foo", "Y"}`, nil, nil, &SyntaxError{"invalid character '}' after object key", 17}},
|
{`{"X": "foo", "Y"}`, nil, nil, &SyntaxError{"invalid character '}' after object key", 17}},
|
||||||
|
|
||||||
|
@ -38,11 +38,11 @@ import (
|
|||||||
//
|
//
|
||||||
// Struct values encode as JSON objects. Each exported struct field
|
// Struct values encode as JSON objects. Each exported struct field
|
||||||
// becomes a member of the object. By default the object's key string
|
// becomes a member of the object. By default the object's key string
|
||||||
// is the struct field name. If the struct field's tag has a "json" key with a
|
// is the struct field name. If the struct field's tag has a "json"
|
||||||
// value that is a non-empty string consisting of only Unicode letters,
|
// key with a value that is a non-empty string consisting of only
|
||||||
// digits, and underscores, that value will be used as the object key.
|
// Unicode letters, digits, dollar signs, hyphens, and underscores,
|
||||||
// For example, the field tag `json:"myName"` says to use "myName"
|
// that value will be used as the object key. For example, the field
|
||||||
// as the object key.
|
// tag `json:"myName"` says to use "myName" as the object key.
|
||||||
//
|
//
|
||||||
// Map values encode as JSON objects.
|
// Map values encode as JSON objects.
|
||||||
// The map's key type must be string; the object keys are used directly
|
// The map's key type must be string; the object keys are used directly
|
||||||
@ -316,7 +316,7 @@ func isValidTag(s string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
for _, c := range s {
|
for _, c := range s {
|
||||||
if c != '_' && !unicode.IsLetter(c) && !unicode.IsDigit(c) {
|
if c != '$' && c != '-' && c != '_' && !unicode.IsLetter(c) && !unicode.IsDigit(c) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
95
src/pkg/json/tagkey_test.go
Normal file
95
src/pkg/json/tagkey_test.go
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
// Copyright 2011 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package json
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
type basicLatin2xTag struct {
|
||||||
|
V string `json:"$-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type basicLatin3xTag struct {
|
||||||
|
V string `json:"0123456789"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type basicLatin4xTag struct {
|
||||||
|
V string `json:"ABCDEFGHIJKLMO"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type basicLatin5xTag struct {
|
||||||
|
V string `json:"PQRSTUVWXYZ_"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type basicLatin6xTag struct {
|
||||||
|
V string `json:"abcdefghijklmno"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type basicLatin7xTag struct {
|
||||||
|
V string `json:"pqrstuvwxyz"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type miscPlaneTag struct {
|
||||||
|
V string `json:"色は匂へど"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type emptyTag struct {
|
||||||
|
W string
|
||||||
|
}
|
||||||
|
|
||||||
|
type misnamedTag struct {
|
||||||
|
X string `jsom:"Misnamed"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type badFormatTag struct {
|
||||||
|
Y string `:"BadFormat"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type badCodeTag struct {
|
||||||
|
Z string `json:" !\"#%&'()*+,./"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var structTagObjectKeyTests = []struct {
|
||||||
|
raw interface{}
|
||||||
|
value string
|
||||||
|
key string
|
||||||
|
}{
|
||||||
|
{basicLatin2xTag{"2x"}, "2x", "$-"},
|
||||||
|
{basicLatin3xTag{"3x"}, "3x", "0123456789"},
|
||||||
|
{basicLatin4xTag{"4x"}, "4x", "ABCDEFGHIJKLMO"},
|
||||||
|
{basicLatin5xTag{"5x"}, "5x", "PQRSTUVWXYZ_"},
|
||||||
|
{basicLatin6xTag{"6x"}, "6x", "abcdefghijklmno"},
|
||||||
|
{basicLatin7xTag{"7x"}, "7x", "pqrstuvwxyz"},
|
||||||
|
{miscPlaneTag{"いろはにほへと"}, "いろはにほへと", "色は匂へど"},
|
||||||
|
{emptyTag{"Pour Moi"}, "Pour Moi", "W"},
|
||||||
|
{misnamedTag{"Animal Kingdom"}, "Animal Kingdom", "X"},
|
||||||
|
{badFormatTag{"Orfevre"}, "Orfevre", "Y"},
|
||||||
|
{badCodeTag{"Reliable Man"}, "Reliable Man", "Z"},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStructTagObjectKey(t *testing.T) {
|
||||||
|
for _, tt := range structTagObjectKeyTests {
|
||||||
|
b, err := Marshal(tt.raw)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Marshal(%#q) failed: %v", tt.raw, err)
|
||||||
|
}
|
||||||
|
var f interface{}
|
||||||
|
err = Unmarshal(b, &f)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unmarshal(%#q) failed: %v", b, err)
|
||||||
|
}
|
||||||
|
for i, v := range f.(map[string]interface{}) {
|
||||||
|
switch i {
|
||||||
|
case tt.key:
|
||||||
|
if s, ok := v.(string); !ok || s != tt.value {
|
||||||
|
t.Fatalf("Unexpected value: %#q, want %v", s, tt.value)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
t.Fatalf("Unexpected key: %#q", i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user