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
2da1865f
Commit
2da1865f
authored
Dec 23, 2014
by
Jordan Liggitt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make default conversion behavior available to conversion funcs
parent
22a241aa
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
78 additions
and
2 deletions
+78
-2
converter.go
pkg/conversion/converter.go
+37
-1
converter_test.go
pkg/conversion/converter_test.go
+41
-1
No files found.
pkg/conversion/converter.go
View file @
2da1865f
...
...
@@ -78,6 +78,10 @@ type Scope interface {
// parameters, you'll run out of stack space before anything useful happens.
Convert
(
src
,
dest
interface
{},
flags
FieldMatchingFlags
)
error
// DefaultConvert performs the default conversion, without calling a conversion func
// on the current stack frame. This makes it safe to call from a conversion func.
DefaultConvert
(
src
,
dest
interface
{},
flags
FieldMatchingFlags
)
error
// SrcTags and DestTags contain the struct tags that src and dest had, respectively.
// If the enclosing object was not a struct, then these will contain no tags, of course.
SrcTag
()
reflect
.
StructTag
...
...
@@ -167,6 +171,12 @@ func (s *scope) Convert(src, dest interface{}, flags FieldMatchingFlags) error {
return
s
.
converter
.
Convert
(
src
,
dest
,
flags
,
s
.
meta
)
}
// DefaultConvert continues a conversion, performing a default conversion (no conversion func)
// for the current stack frame.
func
(
s
*
scope
)
DefaultConvert
(
src
,
dest
interface
{},
flags
FieldMatchingFlags
)
error
{
return
s
.
converter
.
DefaultConvert
(
src
,
dest
,
flags
,
s
.
meta
)
}
// SrcTag returns the tag of the struct containing the current source item, if any.
func
(
s
*
scope
)
SrcTag
()
reflect
.
StructTag
{
return
s
.
srcStack
.
top
()
.
tag
...
...
@@ -296,6 +306,24 @@ func (f FieldMatchingFlags) IsSet(flag FieldMatchingFlags) bool {
// it is not used by Convert() other than storing it in the scope.
// Not safe for objects with cyclic references!
func
(
c
*
Converter
)
Convert
(
src
,
dest
interface
{},
flags
FieldMatchingFlags
,
meta
*
Meta
)
error
{
return
c
.
doConversion
(
src
,
dest
,
flags
,
meta
,
c
.
convert
)
}
// DefaultConvert will translate src to dest if it knows how. Both must be pointers.
// No conversion func is used. If the default copying mechanism
// doesn't work on this type pair, an error will be returned.
// Read the comments on the various FieldMatchingFlags constants to understand
// what the 'flags' parameter does.
// 'meta' is given to allow you to pass information to conversion functions,
// it is not used by DefaultConvert() other than storing it in the scope.
// Not safe for objects with cyclic references!
func
(
c
*
Converter
)
DefaultConvert
(
src
,
dest
interface
{},
flags
FieldMatchingFlags
,
meta
*
Meta
)
error
{
return
c
.
doConversion
(
src
,
dest
,
flags
,
meta
,
c
.
defaultConvert
)
}
type
conversionFunc
func
(
sv
,
dv
reflect
.
Value
,
scope
*
scope
)
error
func
(
c
*
Converter
)
doConversion
(
src
,
dest
interface
{},
flags
FieldMatchingFlags
,
meta
*
Meta
,
f
conversionFunc
)
error
{
dv
,
err
:=
EnforcePtr
(
dest
)
if
err
!=
nil
{
return
err
...
...
@@ -315,7 +343,7 @@ func (c *Converter) Convert(src, dest interface{}, flags FieldMatchingFlags, met
// Leave something on the stack, so that calls to struct tag getters never fail.
s
.
srcStack
.
push
(
scopeStackElem
{})
s
.
destStack
.
push
(
scopeStackElem
{})
return
c
.
convert
(
sv
,
dv
,
s
)
return
f
(
sv
,
dv
,
s
)
}
// callCustom calls 'custom' with sv & dv. custom must be a conversion function.
...
...
@@ -358,6 +386,14 @@ func (c *Converter) convert(sv, dv reflect.Value, scope *scope) error {
return
c
.
callCustom
(
sv
,
dv
,
fv
,
scope
)
}
return
c
.
defaultConvert
(
sv
,
dv
,
scope
)
}
// defaultConvert recursively copies sv into dv. no conversion function is called
// for the current stack frame (but conversion functions may be called for nested objects)
func
(
c
*
Converter
)
defaultConvert
(
sv
,
dv
reflect
.
Value
,
scope
*
scope
)
error
{
dt
,
st
:=
dv
.
Type
(),
sv
.
Type
()
if
!
scope
.
flags
.
IsSet
(
AllowDifferentFieldTypeNames
)
&&
c
.
NameFunc
(
dt
)
!=
c
.
NameFunc
(
st
)
{
return
scope
.
error
(
"type names don't match (%v, %v)"
,
c
.
NameFunc
(
st
),
c
.
NameFunc
(
dt
))
}
...
...
pkg/conversion/converter_test.go
View file @
2da1865f
...
...
@@ -25,6 +25,47 @@ import (
"github.com/google/gofuzz"
)
func
TestConverter_DefaultConvert
(
t
*
testing
.
T
)
{
type
A
struct
{
Foo
string
Baz
int
}
type
B
struct
{
Bar
string
Baz
int
}
c
:=
NewConverter
()
c
.
Debug
=
t
c
.
NameFunc
=
func
(
t
reflect
.
Type
)
string
{
return
"MyType"
}
// Ensure conversion funcs can call DefaultConvert to get default behavior,
// then fixup remaining fields manually
err
:=
c
.
Register
(
func
(
in
*
A
,
out
*
B
,
s
Scope
)
error
{
if
err
:=
s
.
DefaultConvert
(
in
,
out
,
IgnoreMissingFields
);
err
!=
nil
{
return
err
}
out
.
Bar
=
in
.
Foo
return
nil
})
if
err
!=
nil
{
t
.
Fatalf
(
"unexpected error %v"
,
err
)
}
x
:=
A
{
"hello, intrepid test reader!"
,
3
}
y
:=
B
{}
err
=
c
.
Convert
(
&
x
,
&
y
,
0
,
nil
)
if
err
!=
nil
{
t
.
Fatalf
(
"unexpected error %v"
,
err
)
}
if
e
,
a
:=
x
.
Foo
,
y
.
Bar
;
e
!=
a
{
t
.
Errorf
(
"expected %v, got %v"
,
e
,
a
)
}
if
e
,
a
:=
x
.
Baz
,
y
.
Baz
;
e
!=
a
{
t
.
Errorf
(
"expected %v, got %v"
,
e
,
a
)
}
}
func
TestConverter_CallsRegisteredFunctions
(
t
*
testing
.
T
)
{
type
A
struct
{
Foo
string
...
...
@@ -86,7 +127,6 @@ func TestConverter_CallsRegisteredFunctions(t *testing.T) {
if
err
!=
nil
{
t
.
Fatalf
(
"unexpected error %v"
,
err
)
}
err
=
c
.
Convert
(
&
A
{},
&
C
{},
0
,
nil
)
if
err
==
nil
{
t
.
Errorf
(
"unexpected non-error"
)
...
...
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