mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-20 18:31:15 +00:00
Merge pull request #395 from thockin/cleanups
IntOrString for use in JSON/YAML
This commit is contained in:
commit
e6ee45d38e
@ -64,3 +64,66 @@ func MakeJSONString(o interface{}) string {
|
||||
data, _ := json.Marshal(o)
|
||||
return string(data)
|
||||
}
|
||||
|
||||
// IntOrString is a type that can hold an int or a string. When used in
|
||||
// JSON or YAML marshalling and unmarshalling, it produces or consumes the
|
||||
// inner type. This allows you to have, for example, a JSON field that can
|
||||
// accept a name or number.
|
||||
type IntOrString struct {
|
||||
Kind IntstrKind
|
||||
IntVal int
|
||||
StrVal string
|
||||
}
|
||||
|
||||
type IntstrKind int
|
||||
|
||||
const (
|
||||
IntstrInt IntstrKind = iota
|
||||
IntstrString
|
||||
)
|
||||
|
||||
func (intstr *IntOrString) SetYAML(tag string, value interface{}) bool {
|
||||
if intVal, ok := value.(int); ok {
|
||||
intstr.Kind = IntstrInt
|
||||
intstr.IntVal = intVal
|
||||
return true
|
||||
}
|
||||
if strVal, ok := value.(string); ok {
|
||||
intstr.Kind = IntstrString
|
||||
intstr.StrVal = strVal
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (intstr IntOrString) GetYAML() (tag string, value interface{}) {
|
||||
switch intstr.Kind {
|
||||
case IntstrInt:
|
||||
value = intstr.IntVal
|
||||
case IntstrString:
|
||||
value = intstr.StrVal
|
||||
default:
|
||||
panic("impossible IntOrString.Kind")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (intstr *IntOrString) UnmarshalJSON(value []byte) error {
|
||||
if value[0] == '"' {
|
||||
intstr.Kind = IntstrString
|
||||
return json.Unmarshal(value, &intstr.StrVal)
|
||||
}
|
||||
intstr.Kind = IntstrInt
|
||||
return json.Unmarshal(value, &intstr.IntVal)
|
||||
}
|
||||
|
||||
func (intstr IntOrString) MarshalJSON() ([]byte, error) {
|
||||
switch intstr.Kind {
|
||||
case IntstrInt:
|
||||
return json.Marshal(intstr.IntVal)
|
||||
case IntstrString:
|
||||
return json.Marshal(intstr.StrVal)
|
||||
default:
|
||||
panic("impossible IntOrString.Kind")
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ package util
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"gopkg.in/v1/yaml"
|
||||
)
|
||||
|
||||
type FakeJSONBase struct {
|
||||
@ -65,3 +67,127 @@ func TestHandleCrash(t *testing.T) {
|
||||
t.Errorf("Expected %d iterations, found %d", expect, count)
|
||||
}
|
||||
}
|
||||
|
||||
type IntOrStringHolder struct {
|
||||
IOrS IntOrString `json:"val" yaml:"val"`
|
||||
}
|
||||
|
||||
func TestIntOrStringUnmarshalYAML(t *testing.T) {
|
||||
{
|
||||
yaml_code_int := "val: 123\n"
|
||||
|
||||
var result IntOrStringHolder
|
||||
if err := yaml.Unmarshal([]byte(yaml_code_int), &result); err != nil {
|
||||
t.Errorf("Failed to unmarshal: %v", err)
|
||||
}
|
||||
if result.IOrS.Kind != IntstrInt || result.IOrS.IntVal != 123 {
|
||||
t.Errorf("Failed to unmarshal int-typed IntOrString: %v", result)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
yaml_code_str := "val: \"123\"\n"
|
||||
|
||||
var result IntOrStringHolder
|
||||
if err := yaml.Unmarshal([]byte(yaml_code_str), &result); err != nil {
|
||||
t.Errorf("Failed to unmarshal: %v", err)
|
||||
}
|
||||
if result.IOrS.Kind != IntstrString || result.IOrS.StrVal != "123" {
|
||||
t.Errorf("Failed to unmarshal string-typed IntOrString: %v", result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIntOrStringMarshalYAML(t *testing.T) {
|
||||
{
|
||||
input := IntOrStringHolder{
|
||||
IOrS: IntOrString{
|
||||
Kind: IntstrInt,
|
||||
IntVal: 123,
|
||||
},
|
||||
}
|
||||
result, err := yaml.Marshal(&input)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to marshal: %v", err)
|
||||
}
|
||||
if string(result) != "val: 123\n" {
|
||||
t.Errorf("Failed to marshal int-typed IntOrString: %q", string(result))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
input := IntOrStringHolder{
|
||||
IOrS: IntOrString{
|
||||
Kind: IntstrString,
|
||||
StrVal: "123",
|
||||
},
|
||||
}
|
||||
result, err := yaml.Marshal(&input)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to marshal: %v", err)
|
||||
}
|
||||
if string(result) != "val: \"123\"\n" {
|
||||
t.Errorf("Failed to marshal string-typed IntOrString: %q", string(result))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIntOrStringUnmarshalJSON(t *testing.T) {
|
||||
{
|
||||
json_code_int := "{\"val\": 123}"
|
||||
|
||||
var result IntOrStringHolder
|
||||
if err := json.Unmarshal([]byte(json_code_int), &result); err != nil {
|
||||
t.Errorf("Failed to unmarshal: %v", err)
|
||||
}
|
||||
if result.IOrS.Kind != IntstrInt || result.IOrS.IntVal != 123 {
|
||||
t.Errorf("Failed to unmarshal int-typed IntOrString: %v", result)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
json_code_str := "{\"val\": \"123\"}"
|
||||
|
||||
var result IntOrStringHolder
|
||||
if err := json.Unmarshal([]byte(json_code_str), &result); err != nil {
|
||||
t.Errorf("Failed to unmarshal: %v", err)
|
||||
}
|
||||
if result.IOrS.Kind != IntstrString || result.IOrS.StrVal != "123" {
|
||||
t.Errorf("Failed to unmarshal string-typed IntOrString: %v", result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIntOrStringMarshalJSON(t *testing.T) {
|
||||
{
|
||||
input := IntOrStringHolder{
|
||||
IOrS: IntOrString{
|
||||
Kind: IntstrInt,
|
||||
IntVal: 123,
|
||||
},
|
||||
}
|
||||
result, err := json.Marshal(&input)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to marshal: %v", err)
|
||||
}
|
||||
if string(result) != "{\"val\":123}" {
|
||||
t.Errorf("Failed to marshal int-typed IntOrString: %q", string(result))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
input := IntOrStringHolder{
|
||||
IOrS: IntOrString{
|
||||
Kind: IntstrString,
|
||||
StrVal: "123",
|
||||
},
|
||||
}
|
||||
result, err := json.Marshal(&input)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to marshal: %v", err)
|
||||
}
|
||||
if string(result) != "{\"val\":\"123\"}" {
|
||||
t.Errorf("Failed to marshal string-typed IntOrString: %q", string(result))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user