mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-28 22:17:14 +00:00
Add stack of previous values to converter
This commit is contained in:
parent
7f2d0c0f71
commit
77521a33d3
@ -100,32 +100,34 @@ type Meta struct {
|
|||||||
|
|
||||||
// scope contains information about an ongoing conversion.
|
// scope contains information about an ongoing conversion.
|
||||||
type scope struct {
|
type scope struct {
|
||||||
converter *Converter
|
converter *Converter
|
||||||
meta *Meta
|
meta *Meta
|
||||||
flags FieldMatchingFlags
|
flags FieldMatchingFlags
|
||||||
srcTagStack []reflect.StructTag
|
|
||||||
destTagStack []reflect.StructTag
|
// srcStack & destStack are separate because they may not have a 1:1
|
||||||
|
// relationship.
|
||||||
|
srcStack scopeStack
|
||||||
|
destStack scopeStack
|
||||||
}
|
}
|
||||||
|
|
||||||
// push adds a level to the src/dest tag stacks.
|
type scopeStackElem struct {
|
||||||
func (s *scope) push() {
|
tag reflect.StructTag
|
||||||
s.srcTagStack = append(s.srcTagStack, "")
|
value reflect.Value
|
||||||
s.destTagStack = append(s.destTagStack, "")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// pop removes a level to the src/dest tag stacks.
|
type scopeStack []scopeStackElem
|
||||||
func (s *scope) pop() {
|
|
||||||
n := len(s.srcTagStack)
|
func (s *scopeStack) pop() {
|
||||||
s.srcTagStack = s.srcTagStack[:n-1]
|
n := len(*s)
|
||||||
s.destTagStack = s.destTagStack[:n-1]
|
*s = (*s)[:n-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *scope) setSrcTag(tag reflect.StructTag) {
|
func (s *scopeStack) push(e scopeStackElem) {
|
||||||
s.srcTagStack[len(s.srcTagStack)-1] = tag
|
*s = append(*s, e)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *scope) setDestTag(tag reflect.StructTag) {
|
func (s *scopeStack) top() *scopeStackElem {
|
||||||
s.destTagStack[len(s.destTagStack)-1] = tag
|
return &(*s)[len(*s)-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert continues a conversion.
|
// Convert continues a conversion.
|
||||||
@ -135,12 +137,12 @@ func (s *scope) Convert(src, dest interface{}, flags FieldMatchingFlags) error {
|
|||||||
|
|
||||||
// SrcTag returns the tag of the struct containing the current source item, if any.
|
// SrcTag returns the tag of the struct containing the current source item, if any.
|
||||||
func (s *scope) SrcTag() reflect.StructTag {
|
func (s *scope) SrcTag() reflect.StructTag {
|
||||||
return s.srcTagStack[len(s.srcTagStack)-1]
|
return s.srcStack.top().tag
|
||||||
}
|
}
|
||||||
|
|
||||||
// DestTag returns the tag of the struct containing the current dest item, if any.
|
// DestTag returns the tag of the struct containing the current dest item, if any.
|
||||||
func (s *scope) DestTag() reflect.StructTag {
|
func (s *scope) DestTag() reflect.StructTag {
|
||||||
return s.destTagStack[len(s.destTagStack)-1]
|
return s.destStack.top().tag
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flags returns the flags with which the current conversion was started.
|
// Flags returns the flags with which the current conversion was started.
|
||||||
@ -265,7 +267,9 @@ func (c *Converter) Convert(src, dest interface{}, flags FieldMatchingFlags, met
|
|||||||
flags: flags,
|
flags: flags,
|
||||||
meta: meta,
|
meta: meta,
|
||||||
}
|
}
|
||||||
s.push() // Easy way to make SrcTag and DestTag never fail
|
// 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 c.convert(sv, dv, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -305,8 +309,10 @@ func (c *Converter) convert(sv, dv reflect.Value, scope *scope) error {
|
|||||||
c.Debug.Logf("Trying to convert '%v' to '%v'", st, dt)
|
c.Debug.Logf("Trying to convert '%v' to '%v'", st, dt)
|
||||||
}
|
}
|
||||||
|
|
||||||
scope.push()
|
scope.srcStack.push(scopeStackElem{value: sv})
|
||||||
defer scope.pop()
|
scope.destStack.push(scopeStackElem{value: dv})
|
||||||
|
defer scope.srcStack.pop()
|
||||||
|
defer scope.destStack.pop()
|
||||||
|
|
||||||
switch dv.Kind() {
|
switch dv.Kind() {
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
@ -375,11 +381,11 @@ func (c *Converter) convertStruct(sv, dv reflect.Value, scope *scope) error {
|
|||||||
if sf.IsValid() {
|
if sf.IsValid() {
|
||||||
// No need to check error, since we know it's valid.
|
// No need to check error, since we know it's valid.
|
||||||
field, _ := st.FieldByName(f.Name)
|
field, _ := st.FieldByName(f.Name)
|
||||||
scope.setSrcTag(field.Tag)
|
scope.srcStack.top().tag = field.Tag
|
||||||
}
|
}
|
||||||
if df.IsValid() {
|
if df.IsValid() {
|
||||||
field, _ := dt.FieldByName(f.Name)
|
field, _ := dt.FieldByName(f.Name)
|
||||||
scope.setDestTag(field.Tag)
|
scope.destStack.top().tag = field.Tag
|
||||||
}
|
}
|
||||||
// TODO: set top level of scope.src/destTagStack with these field tags here.
|
// TODO: set top level of scope.src/destTagStack with these field tags here.
|
||||||
if !df.IsValid() || !sf.IsValid() {
|
if !df.IsValid() || !sf.IsValid() {
|
||||||
|
Loading…
Reference in New Issue
Block a user