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
3c1d51b1
Commit
3c1d51b1
authored
Nov 26, 2014
by
Daniel Smith
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactor to hide structs behind an interface
parent
564c0870
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
85 additions
and
30 deletions
+85
-30
converter.go
pkg/conversion/converter.go
+85
-30
No files found.
pkg/conversion/converter.go
View file @
3c1d51b1
...
@@ -361,7 +361,7 @@ func (c *Converter) convert(sv, dv reflect.Value, scope *scope) error {
...
@@ -361,7 +361,7 @@ func (c *Converter) convert(sv, dv reflect.Value, scope *scope) error {
switch
dv
.
Kind
()
{
switch
dv
.
Kind
()
{
case
reflect
.
Struct
:
case
reflect
.
Struct
:
return
c
.
convert
Struct
(
sv
,
dv
,
scope
)
return
c
.
convert
KV
(
toKVValue
(
sv
),
toKVValue
(
dv
)
,
scope
)
case
reflect
.
Slice
:
case
reflect
.
Slice
:
if
sv
.
IsNil
()
{
if
sv
.
IsNil
()
{
// Don't make a zero-length slice.
// Don't make a zero-length slice.
...
@@ -408,46 +408,99 @@ func (c *Converter) convert(sv, dv reflect.Value, scope *scope) error {
...
@@ -408,46 +408,99 @@ func (c *Converter) convert(sv, dv reflect.Value, scope *scope) error {
return
nil
return
nil
}
}
func
(
c
*
Converter
)
convertStruct
(
sv
,
dv
reflect
.
Value
,
scope
*
scope
)
error
{
func
toKVValue
(
v
reflect
.
Value
)
kvValue
{
dt
,
st
:=
dv
.
Type
(),
sv
.
Type
()
switch
v
.
Kind
()
{
case
reflect
.
Struct
:
return
structAdaptor
(
v
)
}
return
nil
}
// kvValue lets us write the same conversion logic to work with both maps
// and structs. Only maps with string keys make sense for this.
type
kvValue
interface
{
// returns all keys, as a []string.
keys
()
[]
string
// Will just return "" for maps.
tagOf
(
key
string
)
reflect
.
StructTag
// Will return the zero Value if the key doesn't exist.
value
(
key
string
)
reflect
.
Value
// Maps require explict setting-- will do nothing for structs.
// Returns false on failure.
confirmSet
(
key
string
,
v
reflect
.
Value
)
bool
}
type
structAdaptor
reflect
.
Value
func
(
sa
structAdaptor
)
len
()
int
{
v
:=
reflect
.
Value
(
sa
)
return
v
.
Type
()
.
NumField
()
}
func
(
sa
structAdaptor
)
keys
()
[]
string
{
v
:=
reflect
.
Value
(
sa
)
t
:=
v
.
Type
()
keys
:=
make
([]
string
,
t
.
NumField
())
for
i
:=
range
keys
{
keys
[
i
]
=
t
.
Field
(
i
)
.
Name
}
return
keys
}
func
(
sa
structAdaptor
)
tagOf
(
key
string
)
reflect
.
StructTag
{
v
:=
reflect
.
Value
(
sa
)
field
,
ok
:=
v
.
Type
()
.
FieldByName
(
key
)
if
ok
{
return
field
.
Tag
}
return
""
}
func
(
sa
structAdaptor
)
value
(
key
string
)
reflect
.
Value
{
v
:=
reflect
.
Value
(
sa
)
return
v
.
FieldByName
(
key
)
}
listType
:=
dt
func
(
sa
structAdaptor
)
confirmSet
(
key
string
,
v
reflect
.
Value
)
bool
{
return
true
}
// convertKV can convert things that consist of key/value pairs, like structs
// and some maps.
func
(
c
*
Converter
)
convertKV
(
skv
,
dkv
kvValue
,
scope
*
scope
)
error
{
if
skv
==
nil
||
dkv
==
nil
{
// TODO: add keys to stack to support really understandable error messages.
return
fmt
.
Errorf
(
"Unable to convert %#v to %#v"
,
skv
,
dkv
)
}
lister
:=
dkv
if
scope
.
flags
.
IsSet
(
SourceToDest
)
{
if
scope
.
flags
.
IsSet
(
SourceToDest
)
{
list
Type
=
st
list
er
=
skv
}
}
for
i
:=
0
;
i
<
listType
.
NumField
();
i
++
{
for
_
,
key
:=
range
lister
.
keys
()
{
f
:=
listType
.
Field
(
i
)
if
found
,
err
:=
c
.
checkField
(
key
,
skv
,
dkv
,
scope
);
found
{
if
found
,
err
:=
c
.
checkStructField
(
f
.
Name
,
sv
,
dv
,
scope
);
found
{
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
continue
continue
}
}
df
:=
dv
.
FieldByName
(
f
.
Name
)
df
:=
dkv
.
value
(
key
)
sf
:=
sv
.
FieldByName
(
f
.
Name
)
sf
:=
skv
.
value
(
key
)
if
sf
.
IsValid
()
{
// No need to check error, since we know it's valid.
field
,
_
:=
st
.
FieldByName
(
f
.
Name
)
scope
.
srcStack
.
top
()
.
tag
=
field
.
Tag
}
if
df
.
IsValid
()
{
field
,
_
:=
dt
.
FieldByName
(
f
.
Name
)
scope
.
destStack
.
top
()
.
tag
=
field
.
Tag
}
// TODO: set top level of scope.src/destTagStack with these field tags here.
if
!
df
.
IsValid
()
||
!
sf
.
IsValid
()
{
if
!
df
.
IsValid
()
||
!
sf
.
IsValid
()
{
switch
{
switch
{
case
scope
.
flags
.
IsSet
(
IgnoreMissingFields
)
:
case
scope
.
flags
.
IsSet
(
IgnoreMissingFields
)
:
// No error.
// No error.
case
scope
.
flags
.
IsSet
(
SourceToDest
)
:
case
scope
.
flags
.
IsSet
(
SourceToDest
)
:
return
scope
.
error
(
"%v not present in dest
(%v to %v)"
,
f
.
Name
,
st
,
dt
)
return
scope
.
error
(
"%v not present in dest
"
,
key
)
default
:
default
:
return
scope
.
error
(
"%v not present in src
(%v to %v)"
,
f
.
Name
,
st
,
dt
)
return
scope
.
error
(
"%v not present in src
"
,
key
)
}
}
continue
continue
}
}
scope
.
srcStack
.
top
()
.
key
=
f
.
Name
scope
.
srcStack
.
top
()
.
key
=
key
scope
.
srcStack
.
top
()
.
key
=
f
.
Name
scope
.
srcStack
.
top
()
.
tag
=
skv
.
tagOf
(
key
)
scope
.
destStack
.
top
()
.
key
=
key
scope
.
destStack
.
top
()
.
tag
=
dkv
.
tagOf
(
key
)
if
err
:=
c
.
convert
(
sf
,
df
,
scope
);
err
!=
nil
{
if
err
:=
c
.
convert
(
sf
,
df
,
scope
);
err
!=
nil
{
return
err
return
err
}
}
...
@@ -455,12 +508,12 @@ func (c *Converter) convertStruct(sv, dv reflect.Value, scope *scope) error {
...
@@ -455,12 +508,12 @@ func (c *Converter) convertStruct(sv, dv reflect.Value, scope *scope) error {
return
nil
return
nil
}
}
// check
Struct
Field returns true if the field name matches any of the struct
// checkField returns true if the field name matches any of the struct
// field copying rules. The error should be ignored if it returns false.
// field copying rules. The error should be ignored if it returns false.
func
(
c
*
Converter
)
check
StructField
(
fieldName
string
,
sv
,
dv
reflect
.
Value
,
scope
*
scope
)
(
bool
,
error
)
{
func
(
c
*
Converter
)
check
Field
(
fieldName
string
,
skv
,
dkv
kv
Value
,
scope
*
scope
)
(
bool
,
error
)
{
replacementMade
:=
false
replacementMade
:=
false
if
scope
.
flags
.
IsSet
(
DestFromSource
)
{
if
scope
.
flags
.
IsSet
(
DestFromSource
)
{
df
:=
d
v
.
FieldByNam
e
(
fieldName
)
df
:=
d
kv
.
valu
e
(
fieldName
)
if
!
df
.
IsValid
()
{
if
!
df
.
IsValid
()
{
return
false
,
nil
return
false
,
nil
}
}
...
@@ -468,7 +521,7 @@ func (c *Converter) checkStructField(fieldName string, sv, dv reflect.Value, sco
...
@@ -468,7 +521,7 @@ func (c *Converter) checkStructField(fieldName string, sv, dv reflect.Value, sco
// Check each of the potential source (type, name) pairs to see if they're
// Check each of the potential source (type, name) pairs to see if they're
// present in sv.
// present in sv.
for
_
,
potentialSourceKey
:=
range
c
.
structFieldSources
[
destKey
]
{
for
_
,
potentialSourceKey
:=
range
c
.
structFieldSources
[
destKey
]
{
sf
:=
s
v
.
FieldByNam
e
(
potentialSourceKey
.
fieldName
)
sf
:=
s
kv
.
valu
e
(
potentialSourceKey
.
fieldName
)
if
!
sf
.
IsValid
()
{
if
!
sf
.
IsValid
()
{
continue
continue
}
}
...
@@ -479,13 +532,14 @@ func (c *Converter) checkStructField(fieldName string, sv, dv reflect.Value, sco
...
@@ -479,13 +532,14 @@ func (c *Converter) checkStructField(fieldName string, sv, dv reflect.Value, sco
if
err
:=
c
.
convert
(
sf
,
df
,
scope
);
err
!=
nil
{
if
err
:=
c
.
convert
(
sf
,
df
,
scope
);
err
!=
nil
{
return
true
,
err
return
true
,
err
}
}
dkv
.
confirmSet
(
fieldName
,
df
)
replacementMade
=
true
replacementMade
=
true
}
}
}
}
return
replacementMade
,
nil
return
replacementMade
,
nil
}
}
sf
:=
s
v
.
FieldByNam
e
(
fieldName
)
sf
:=
s
kv
.
valu
e
(
fieldName
)
if
!
sf
.
IsValid
()
{
if
!
sf
.
IsValid
()
{
return
false
,
nil
return
false
,
nil
}
}
...
@@ -493,7 +547,7 @@ func (c *Converter) checkStructField(fieldName string, sv, dv reflect.Value, sco
...
@@ -493,7 +547,7 @@ func (c *Converter) checkStructField(fieldName string, sv, dv reflect.Value, sco
// Check each of the potential dest (type, name) pairs to see if they're
// Check each of the potential dest (type, name) pairs to see if they're
// present in dv.
// present in dv.
for
_
,
potentialDestKey
:=
range
c
.
structFieldDests
[
srcKey
]
{
for
_
,
potentialDestKey
:=
range
c
.
structFieldDests
[
srcKey
]
{
df
:=
d
v
.
FieldByNam
e
(
potentialDestKey
.
fieldName
)
df
:=
d
kv
.
valu
e
(
potentialDestKey
.
fieldName
)
if
!
df
.
IsValid
()
{
if
!
df
.
IsValid
()
{
continue
continue
}
}
...
@@ -504,6 +558,7 @@ func (c *Converter) checkStructField(fieldName string, sv, dv reflect.Value, sco
...
@@ -504,6 +558,7 @@ func (c *Converter) checkStructField(fieldName string, sv, dv reflect.Value, sco
if
err
:=
c
.
convert
(
sf
,
df
,
scope
);
err
!=
nil
{
if
err
:=
c
.
convert
(
sf
,
df
,
scope
);
err
!=
nil
{
return
true
,
err
return
true
,
err
}
}
dkv
.
confirmSet
(
potentialDestKey
.
fieldName
,
df
)
replacementMade
=
true
replacementMade
=
true
}
}
}
}
...
...
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