Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
5b27f8b8
Unverified
Commit
5b27f8b8
authored
May 11, 2017
by
Jordan Liggitt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix unstructured marshaler to handle all JSON types
parent
ae1ff1a2
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
112 additions
and
24 deletions
+112
-24
converter.go
....io/apimachinery/pkg/conversion/unstructured/converter.go
+55
-24
converter_test.go
...pimachinery/pkg/conversion/unstructured/converter_test.go
+45
-0
json.go
staging/src/k8s.io/apimachinery/pkg/util/json/json.go
+12
-0
No files found.
staging/src/k8s.io/apimachinery/pkg/conversion/unstructured/converter.go
View file @
5b27f8b8
...
...
@@ -420,6 +420,12 @@ func toUnstructuredViaJSON(obj interface{}, u *map[string]interface{}) error {
return
json
.
Unmarshal
(
data
,
u
)
}
var
(
nullBytes
=
[]
byte
(
"null"
)
trueBytes
=
[]
byte
(
"true"
)
falseBytes
=
[]
byte
(
"false"
)
)
func
toUnstructured
(
sv
,
dv
reflect
.
Value
)
error
{
st
,
dt
:=
sv
.
Type
(),
dv
.
Type
()
...
...
@@ -435,33 +441,58 @@ func toUnstructured(sv, dv reflect.Value) error {
if
err
!=
nil
{
return
err
}
if
bytes
.
Equal
(
data
,
[]
byte
(
"null"
))
{
switch
{
case
len
(
data
)
==
0
:
return
fmt
.
Errorf
(
"error decoding from json: empty value"
)
case
bytes
.
Equal
(
data
,
nullBytes
)
:
// We're done - we don't need to store anything.
}
else
{
switch
{
case
len
(
data
)
>
0
&&
data
[
0
]
==
'"'
:
var
result
string
err
:=
json
.
Unmarshal
(
data
,
&
result
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"error decoding from json: %v"
,
err
)
}
dv
.
Set
(
reflect
.
ValueOf
(
result
))
case
len
(
data
)
>
0
&&
data
[
0
]
==
'{'
:
result
:=
make
(
map
[
string
]
interface
{})
err
:=
json
.
Unmarshal
(
data
,
&
result
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"error decoding from json: %v"
,
err
)
}
dv
.
Set
(
reflect
.
ValueOf
(
result
))
default
:
var
result
int64
err
:=
json
.
Unmarshal
(
data
,
&
result
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"error decoding from json: %v"
,
err
)
}
dv
.
Set
(
reflect
.
ValueOf
(
result
))
case
bytes
.
Equal
(
data
,
trueBytes
)
:
dv
.
Set
(
reflect
.
ValueOf
(
true
))
case
bytes
.
Equal
(
data
,
falseBytes
)
:
dv
.
Set
(
reflect
.
ValueOf
(
false
))
case
data
[
0
]
==
'"'
:
var
result
string
err
:=
json
.
Unmarshal
(
data
,
&
result
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"error decoding string from json: %v"
,
err
)
}
dv
.
Set
(
reflect
.
ValueOf
(
result
))
case
data
[
0
]
==
'{'
:
result
:=
make
(
map
[
string
]
interface
{})
err
:=
json
.
Unmarshal
(
data
,
&
result
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"error decoding object from json: %v"
,
err
)
}
dv
.
Set
(
reflect
.
ValueOf
(
result
))
case
data
[
0
]
==
'['
:
result
:=
make
([]
interface
{},
0
)
err
:=
json
.
Unmarshal
(
data
,
&
result
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"error decoding array from json: %v"
,
err
)
}
dv
.
Set
(
reflect
.
ValueOf
(
result
))
default
:
var
(
resultInt
int64
resultFloat
float64
err
error
)
if
err
=
json
.
Unmarshal
(
data
,
&
resultInt
);
err
==
nil
{
dv
.
Set
(
reflect
.
ValueOf
(
resultInt
))
}
else
if
err
=
json
.
Unmarshal
(
data
,
&
resultFloat
);
err
==
nil
{
dv
.
Set
(
reflect
.
ValueOf
(
resultFloat
))
}
else
{
return
fmt
.
Errorf
(
"error decoding number from json: %v"
,
err
)
}
}
return
nil
}
...
...
staging/src/k8s.io/apimachinery/pkg/conversion/unstructured/converter_test.go
View file @
5b27f8b8
...
...
@@ -71,6 +71,18 @@ type F struct {
I
[]
float32
`json:"fi"`
}
type
G
struct
{
Custom
Custom
`json:"custom"`
}
type
Custom
struct
{
data
[]
byte
}
func
(
c
Custom
)
MarshalJSON
()
([]
byte
,
error
)
{
return
c
.
data
,
nil
}
func
doRoundTrip
(
t
*
testing
.
T
,
item
interface
{})
{
data
,
err
:=
json
.
Marshal
(
item
)
if
err
!=
nil
{
...
...
@@ -439,3 +451,36 @@ func TestFloatIntConversion(t *testing.T) {
t
.
Errorf
(
"Incorrect conversion, diff: %v"
,
diff
.
ObjectReflectDiff
(
obj
,
unmarshalled
))
}
}
func
TestCustomToUnstructured
(
t
*
testing
.
T
)
{
testcases
:=
[]
struct
{
Data
string
Expected
interface
{}
}{
{
Data
:
`null`
,
Expected
:
nil
},
{
Data
:
`true`
,
Expected
:
true
},
{
Data
:
`false`
,
Expected
:
false
},
{
Data
:
`[]`
,
Expected
:
[]
interface
{}{}},
{
Data
:
`[1]`
,
Expected
:
[]
interface
{}{
int64
(
1
)}},
{
Data
:
`{}`
,
Expected
:
map
[
string
]
interface
{}{}},
{
Data
:
`{"a":1}`
,
Expected
:
map
[
string
]
interface
{}{
"a"
:
int64
(
1
)}},
{
Data
:
`0`
,
Expected
:
int64
(
0
)},
{
Data
:
`0.0`
,
Expected
:
float64
(
0
)},
}
for
_
,
tc
:=
range
testcases
{
result
,
err
:=
DefaultConverter
.
ToUnstructured
(
&
G
{
Custom
:
Custom
{
data
:
[]
byte
(
tc
.
Data
)}})
if
err
!=
nil
{
t
.
Errorf
(
"%s: %v"
,
tc
.
Data
,
err
)
continue
}
fieldResult
:=
result
[
"custom"
]
if
!
reflect
.
DeepEqual
(
fieldResult
,
tc
.
Expected
)
{
t
.
Errorf
(
"%s: expected %v, got %v"
,
tc
.
Data
,
tc
.
Expected
,
fieldResult
)
// t.Log("expected", spew.Sdump(tc.Expected))
// t.Log("actual", spew.Sdump(fieldResult))
continue
}
}
}
staging/src/k8s.io/apimachinery/pkg/util/json/json.go
View file @
5b27f8b8
...
...
@@ -50,6 +50,18 @@ func Unmarshal(data []byte, v interface{}) error {
// If the decode succeeds, post-process the map to convert json.Number objects to int64 or float64
return
convertMapNumbers
(
*
v
)
case
*
[]
interface
{}
:
// Build a decoder from the given data
decoder
:=
json
.
NewDecoder
(
bytes
.
NewBuffer
(
data
))
// Preserve numbers, rather than casting to float64 automatically
decoder
.
UseNumber
()
// Run the decode
if
err
:=
decoder
.
Decode
(
v
);
err
!=
nil
{
return
err
}
// If the decode succeeds, post-process the map to convert json.Number objects to int64 or float64
return
convertSliceNumbers
(
*
v
)
default
:
return
json
.
Unmarshal
(
data
,
v
)
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment