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
1ddb68d8
Commit
1ddb68d8
authored
Nov 23, 2014
by
Tim Hockin
Committed by
Yu-Ju Hong
Feb 02, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Sketch: a third take on defaulting values
parent
2ac6bbb7
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
164 additions
and
24 deletions
+164
-24
defaults.go
pkg/api/v1beta1/defaults.go
+61
-0
converter.go
pkg/conversion/converter.go
+62
-14
converter_test.go
pkg/conversion/converter_test.go
+7
-7
scheme.go
pkg/conversion/scheme.go
+25
-2
scheme.go
pkg/runtime/scheme.go
+9
-1
No files found.
pkg/api/v1beta1/defaults.go
0 → 100644
View file @
1ddb68d8
/*
Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package
v1beta1
import
(
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
)
func
init
()
{
api
.
Scheme
.
AddDefaultingFuncs
(
func
(
obj
*
Volume
)
{
if
obj
.
Source
==
nil
||
util
.
AllPtrFieldsNil
(
obj
.
Source
)
{
obj
.
Source
=
&
VolumeSource
{
EmptyDir
:
&
EmptyDir
{},
}
}
},
func
(
obj
*
Port
)
{
if
obj
.
Protocol
==
""
{
obj
.
Protocol
=
ProtocolTCP
}
},
func
(
obj
*
Container
)
{
// TODO: delete helper functions that touch this
if
obj
.
ImagePullPolicy
==
""
{
obj
.
ImagePullPolicy
=
PullIfNotPresent
}
if
obj
.
TerminationMessagePath
==
""
{
// TODO: fix other code that sets this
obj
.
TerminationMessagePath
=
api
.
TerminationMessagePathDefault
}
},
func
(
obj
*
RestartPolicy
)
{
if
util
.
AllPtrFieldsNil
(
obj
)
{
obj
.
Always
=
&
RestartPolicyAlways
{}
}
},
func
(
obj
*
Service
)
{
if
obj
.
Protocol
==
""
{
obj
.
Protocol
=
ProtocolTCP
}
},
)
}
// TODO: remove redundant code in validation and conversion
pkg/conversion/converter.go
View file @
1ddb68d8
...
@@ -40,7 +40,7 @@ type DebugLogger interface {
...
@@ -40,7 +40,7 @@ type DebugLogger interface {
type
Converter
struct
{
type
Converter
struct
{
// Map from the conversion pair to a function which can
// Map from the conversion pair to a function which can
// do the conversion.
// do the conversion.
f
uncs
map
[
typePair
]
reflect
.
Value
conversionF
uncs
map
[
typePair
]
reflect
.
Value
// This is a map from a source field type and name, to a list of destination
// This is a map from a source field type and name, to a list of destination
// field type and name.
// field type and name.
...
@@ -51,20 +51,25 @@ type Converter struct {
...
@@ -51,20 +51,25 @@ type Converter struct {
// source field name and type to look for.
// source field name and type to look for.
structFieldSources
map
[
typeNamePair
][]
typeNamePair
structFieldSources
map
[
typeNamePair
][]
typeNamePair
// Map from a type to a function which applies defaults.
defaultingFuncs
map
[
reflect
.
Type
]
reflect
.
Value
// If non-nil, will be called to print helpful debugging info. Quite verbose.
// If non-nil, will be called to print helpful debugging info. Quite verbose.
Debug
DebugLogger
Debug
DebugLogger
//
N
ameFunc is called to retrieve the name of a type; this name is used for the
//
n
ameFunc is called to retrieve the name of a type; this name is used for the
// purpose of deciding whether two types match or not (i.e., will we attempt to
// purpose of deciding whether two types match or not (i.e., will we attempt to
// do a conversion). The default returns the go type name.
// do a conversion). The default returns the go type name.
N
ameFunc
func
(
t
reflect
.
Type
)
string
n
ameFunc
func
(
t
reflect
.
Type
)
string
}
}
// NewConverter creates a new Converter object.
// NewConverter creates a new Converter object.
func
NewConverter
()
*
Converter
{
func
NewConverter
()
*
Converter
{
return
&
Converter
{
return
&
Converter
{
conversionFuncs
:
map
[
typePair
]
reflect
.
Value
{},
defaultingFuncs
:
map
[
reflect
.
Type
]
reflect
.
Value
{},
funcs
:
map
[
typePair
]
reflect
.
Value
{},
funcs
:
map
[
typePair
]
reflect
.
Value
{},
N
ameFunc
:
func
(
t
reflect
.
Type
)
string
{
return
t
.
Name
()
},
n
ameFunc
:
func
(
t
reflect
.
Type
)
string
{
return
t
.
Name
()
},
structFieldDests
:
map
[
typeNamePair
][]
typeNamePair
{},
structFieldDests
:
map
[
typeNamePair
][]
typeNamePair
{},
structFieldSources
:
map
[
typeNamePair
][]
typeNamePair
{},
structFieldSources
:
map
[
typeNamePair
][]
typeNamePair
{},
}
}
...
@@ -210,14 +215,18 @@ func (s *scope) error(message string, args ...interface{}) error {
...
@@ -210,14 +215,18 @@ func (s *scope) error(message string, args ...interface{}) error {
return
fmt
.
Errorf
(
where
+
message
,
args
...
)
return
fmt
.
Errorf
(
where
+
message
,
args
...
)
}
}
// Register
registers a conversion func with the Converter. conversionFunc must tak
e
// Register
ConversionFunc registers a conversion func with th
e
//
three parameters: a pointer to the input type, a pointer to the output type, and
//
Converter. conversionFunc must take three parameters: a pointer to the input
//
a conversion.Scope (which should be used if recursive conversion calls are desired).
//
type, a pointer to the output type, and a conversion.Scope (which should be
// It must return an error.
//
used if recursive conversion calls are desired).
It must return an error.
//
//
// Example:
// Example:
// c.Register(func(in *Pod, out *v1beta1.Pod, s Scope) error { ... return nil })
// c.RegisteConversionFuncr(
func
(
c
*
Converter
)
Register
(
conversionFunc
interface
{})
error
{
// func(in *Pod, out *v1beta1.Pod, s Scope) error {
// // conversion logic...
// return nil
// })
func
(
c
*
Converter
)
RegisterConversionFunc
(
conversionFunc
interface
{})
error
{
fv
:=
reflect
.
ValueOf
(
conversionFunc
)
fv
:=
reflect
.
ValueOf
(
conversionFunc
)
ft
:=
fv
.
Type
()
ft
:=
fv
.
Type
()
if
ft
.
Kind
()
!=
reflect
.
Func
{
if
ft
.
Kind
()
!=
reflect
.
Func
{
...
@@ -246,7 +255,7 @@ func (c *Converter) Register(conversionFunc interface{}) error {
...
@@ -246,7 +255,7 @@ func (c *Converter) Register(conversionFunc interface{}) error {
if
ft
.
Out
(
0
)
!=
errorType
{
if
ft
.
Out
(
0
)
!=
errorType
{
return
fmt
.
Errorf
(
"expected error return, got: %v"
,
ft
)
return
fmt
.
Errorf
(
"expected error return, got: %v"
,
ft
)
}
}
c
.
f
uncs
[
typePair
{
ft
.
In
(
0
)
.
Elem
(),
ft
.
In
(
1
)
.
Elem
()}]
=
fv
c
.
conversionF
uncs
[
typePair
{
ft
.
In
(
0
)
.
Elem
(),
ft
.
In
(
1
)
.
Elem
()}]
=
fv
return
nil
return
nil
}
}
...
@@ -266,6 +275,33 @@ func (c *Converter) SetStructFieldCopy(srcFieldType interface{}, srcFieldName st
...
@@ -266,6 +275,33 @@ func (c *Converter) SetStructFieldCopy(srcFieldType interface{}, srcFieldName st
return
nil
return
nil
}
}
// RegisterDefaultingFunc registers a value-defaulting func with the Converter.
// defaultingFunc must take one parameters: a pointer to the input type.
//
// Example:
// c.RegisteDefaultingFuncr(
// func(in *v1beta1.Pod) {
// // defaulting logic...
// })
func
(
c
*
Converter
)
RegisterDefaultingFunc
(
defaultingFunc
interface
{})
error
{
fv
:=
reflect
.
ValueOf
(
defaultingFunc
)
ft
:=
fv
.
Type
()
if
ft
.
Kind
()
!=
reflect
.
Func
{
return
fmt
.
Errorf
(
"expected func, got: %v"
,
ft
)
}
if
ft
.
NumIn
()
!=
1
{
return
fmt
.
Errorf
(
"expected one 'in' param, got: %v"
,
ft
)
}
if
ft
.
NumOut
()
!=
0
{
return
fmt
.
Errorf
(
"expected zero 'out' params, got: %v"
,
ft
)
}
if
ft
.
In
(
0
)
.
Kind
()
!=
reflect
.
Ptr
{
return
fmt
.
Errorf
(
"expected pointer arg for 'in' param 0, got: %v"
,
ft
)
}
c
.
defaultingFuncs
[
ft
.
In
(
0
)
.
Elem
()]
=
fv
return
nil
}
// FieldMatchingFlags contains a list of ways in which struct fields could be
// FieldMatchingFlags contains a list of ways in which struct fields could be
// copied. These constants may be | combined.
// copied. These constants may be | combined.
type
FieldMatchingFlags
int
type
FieldMatchingFlags
int
...
@@ -379,7 +415,18 @@ func (c *Converter) callCustom(sv, dv, custom reflect.Value, scope *scope) error
...
@@ -379,7 +415,18 @@ func (c *Converter) callCustom(sv, dv, custom reflect.Value, scope *scope) error
// one is registered.
// one is registered.
func
(
c
*
Converter
)
convert
(
sv
,
dv
reflect
.
Value
,
scope
*
scope
)
error
{
func
(
c
*
Converter
)
convert
(
sv
,
dv
reflect
.
Value
,
scope
*
scope
)
error
{
dt
,
st
:=
dv
.
Type
(),
sv
.
Type
()
dt
,
st
:=
dv
.
Type
(),
sv
.
Type
()
if
fv
,
ok
:=
c
.
funcs
[
typePair
{
st
,
dt
}];
ok
{
// Apply default values.
if
fv
,
ok
:=
c
.
defaultingFuncs
[
st
];
ok
{
if
c
.
Debug
!=
nil
{
c
.
Debug
.
Logf
(
"Applying defaults for '%v'"
,
st
)
}
args
:=
[]
reflect
.
Value
{
sv
.
Addr
()}
fv
.
Call
(
args
)
}
// Convert sv to dv.
if
fv
,
ok
:=
c
.
conversionFuncs
[
typePair
{
st
,
dt
}];
ok
{
if
c
.
Debug
!=
nil
{
if
c
.
Debug
!=
nil
{
c
.
Debug
.
Logf
(
"Calling custom conversion of '%v' to '%v'"
,
st
,
dt
)
c
.
Debug
.
Logf
(
"Calling custom conversion of '%v' to '%v'"
,
st
,
dt
)
}
}
...
@@ -398,10 +445,10 @@ func (c *Converter) defaultConvert(sv, dv reflect.Value, scope *scope) error {
...
@@ -398,10 +445,10 @@ func (c *Converter) defaultConvert(sv, dv reflect.Value, scope *scope) error {
return
scope
.
error
(
"Cannot set dest. (Tried to deep copy something with unexported fields?)"
)
return
scope
.
error
(
"Cannot set dest. (Tried to deep copy something with unexported fields?)"
)
}
}
if
!
scope
.
flags
.
IsSet
(
AllowDifferentFieldTypeNames
)
&&
c
.
NameFunc
(
dt
)
!=
c
.
N
ameFunc
(
st
)
{
if
!
scope
.
flags
.
IsSet
(
AllowDifferentFieldTypeNames
)
&&
c
.
nameFunc
(
dt
)
!=
c
.
n
ameFunc
(
st
)
{
return
scope
.
error
(
return
scope
.
error
(
"type names don't match (%v, %v), and no conversion 'func (%v, %v) error' registered."
,
"type names don't match (%v, %v), and no conversion 'func (%v, %v) error' registered."
,
c
.
NameFunc
(
st
),
c
.
N
ameFunc
(
dt
),
st
,
dt
)
c
.
nameFunc
(
st
),
c
.
n
ameFunc
(
dt
),
st
,
dt
)
}
}
switch
st
.
Kind
()
{
switch
st
.
Kind
()
{
...
@@ -498,6 +545,7 @@ func toKVValue(v reflect.Value) kvValue {
...
@@ -498,6 +545,7 @@ func toKVValue(v reflect.Value) kvValue {
case
reflect
.
Struct
:
case
reflect
.
Struct
:
return
structAdaptor
(
v
)
return
structAdaptor
(
v
)
}
}
return
nil
return
nil
}
}
...
...
pkg/conversion/converter_test.go
View file @
1ddb68d8
...
@@ -118,14 +118,14 @@ func TestConverter_CallsRegisteredFunctions(t *testing.T) {
...
@@ -118,14 +118,14 @@ func TestConverter_CallsRegisteredFunctions(t *testing.T) {
type
C
struct
{}
type
C
struct
{}
c
:=
NewConverter
()
c
:=
NewConverter
()
c
.
Debug
=
t
c
.
Debug
=
t
err
:=
c
.
Register
(
func
(
in
*
A
,
out
*
B
,
s
Scope
)
error
{
err
:=
c
.
Register
ConversionFunc
(
func
(
in
*
A
,
out
*
B
,
s
Scope
)
error
{
out
.
Bar
=
in
.
Foo
out
.
Bar
=
in
.
Foo
return
s
.
Convert
(
&
in
.
Baz
,
&
out
.
Baz
,
0
)
return
s
.
Convert
(
&
in
.
Baz
,
&
out
.
Baz
,
0
)
})
})
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatalf
(
"unexpected error %v"
,
err
)
t
.
Fatalf
(
"unexpected error %v"
,
err
)
}
}
err
=
c
.
Register
(
func
(
in
*
B
,
out
*
A
,
s
Scope
)
error
{
err
=
c
.
Register
ConversionFunc
(
func
(
in
*
B
,
out
*
A
,
s
Scope
)
error
{
out
.
Foo
=
in
.
Bar
out
.
Foo
=
in
.
Bar
return
s
.
Convert
(
&
in
.
Baz
,
&
out
.
Baz
,
0
)
return
s
.
Convert
(
&
in
.
Baz
,
&
out
.
Baz
,
0
)
})
})
...
@@ -161,7 +161,7 @@ func TestConverter_CallsRegisteredFunctions(t *testing.T) {
...
@@ -161,7 +161,7 @@ func TestConverter_CallsRegisteredFunctions(t *testing.T) {
t
.
Errorf
(
"expected %v, got %v"
,
e
,
a
)
t
.
Errorf
(
"expected %v, got %v"
,
e
,
a
)
}
}
err
=
c
.
Register
(
func
(
in
*
A
,
out
*
C
,
s
Scope
)
error
{
err
=
c
.
Register
ConversionFunc
(
func
(
in
*
A
,
out
*
C
,
s
Scope
)
error
{
return
fmt
.
Errorf
(
"C can't store an A, silly"
)
return
fmt
.
Errorf
(
"C can't store an A, silly"
)
})
})
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -184,7 +184,7 @@ func TestConverter_fuzz(t *testing.T) {
...
@@ -184,7 +184,7 @@ func TestConverter_fuzz(t *testing.T) {
f
:=
fuzz
.
New
()
.
NilChance
(
.5
)
.
NumElements
(
0
,
100
)
f
:=
fuzz
.
New
()
.
NilChance
(
.5
)
.
NumElements
(
0
,
100
)
c
:=
NewConverter
()
c
:=
NewConverter
()
c
.
N
ameFunc
=
func
(
t
reflect
.
Type
)
string
{
c
.
n
ameFunc
=
func
(
t
reflect
.
Type
)
string
{
// Hide the fact that we don't have separate packages for these things.
// Hide the fact that we don't have separate packages for these things.
return
map
[
reflect
.
Type
]
string
{
return
map
[
reflect
.
Type
]
string
{
reflect
.
TypeOf
(
TestType1
{})
:
"TestType1"
,
reflect
.
TypeOf
(
TestType1
{})
:
"TestType1"
,
...
@@ -270,7 +270,7 @@ func TestConverter_tags(t *testing.T) {
...
@@ -270,7 +270,7 @@ func TestConverter_tags(t *testing.T) {
}
}
c
:=
NewConverter
()
c
:=
NewConverter
()
c
.
Debug
=
t
c
.
Debug
=
t
err
:=
c
.
Register
(
err
:=
c
.
Register
ConversionFunc
(
func
(
in
*
string
,
out
*
string
,
s
Scope
)
error
{
func
(
in
*
string
,
out
*
string
,
s
Scope
)
error
{
if
e
,
a
:=
"foo"
,
s
.
SrcTag
()
.
Get
(
"test"
);
e
!=
a
{
if
e
,
a
:=
"foo"
,
s
.
SrcTag
()
.
Get
(
"test"
);
e
!=
a
{
t
.
Errorf
(
"expected %v, got %v"
,
e
,
a
)
t
.
Errorf
(
"expected %v, got %v"
,
e
,
a
)
...
@@ -296,7 +296,7 @@ func TestConverter_meta(t *testing.T) {
...
@@ -296,7 +296,7 @@ func TestConverter_meta(t *testing.T) {
c
:=
NewConverter
()
c
:=
NewConverter
()
c
.
Debug
=
t
c
.
Debug
=
t
checks
:=
0
checks
:=
0
err
:=
c
.
Register
(
err
:=
c
.
Register
ConversionFunc
(
func
(
in
*
Foo
,
out
*
Bar
,
s
Scope
)
error
{
func
(
in
*
Foo
,
out
*
Bar
,
s
Scope
)
error
{
if
s
.
Meta
()
==
nil
||
s
.
Meta
()
.
SrcVersion
!=
"test"
||
s
.
Meta
()
.
DestVersion
!=
"passes"
{
if
s
.
Meta
()
==
nil
||
s
.
Meta
()
.
SrcVersion
!=
"test"
||
s
.
Meta
()
.
DestVersion
!=
"passes"
{
t
.
Errorf
(
"Meta did not get passed!"
)
t
.
Errorf
(
"Meta did not get passed!"
)
...
@@ -309,7 +309,7 @@ func TestConverter_meta(t *testing.T) {
...
@@ -309,7 +309,7 @@ func TestConverter_meta(t *testing.T) {
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatalf
(
"Unexpected error: %v"
,
err
)
t
.
Fatalf
(
"Unexpected error: %v"
,
err
)
}
}
err
=
c
.
Register
(
err
=
c
.
Register
ConversionFunc
(
func
(
in
*
string
,
out
*
string
,
s
Scope
)
error
{
func
(
in
*
string
,
out
*
string
,
s
Scope
)
error
{
if
s
.
Meta
()
==
nil
||
s
.
Meta
()
.
SrcVersion
!=
"test"
||
s
.
Meta
()
.
DestVersion
!=
"passes"
{
if
s
.
Meta
()
==
nil
||
s
.
Meta
()
.
SrcVersion
!=
"test"
||
s
.
Meta
()
.
DestVersion
!=
"passes"
{
t
.
Errorf
(
"Meta did not get passed a second time!"
)
t
.
Errorf
(
"Meta did not get passed a second time!"
)
...
...
pkg/conversion/scheme.go
View file @
1ddb68d8
...
@@ -63,7 +63,7 @@ func NewScheme() *Scheme {
...
@@ -63,7 +63,7 @@ func NewScheme() *Scheme {
InternalVersion
:
""
,
InternalVersion
:
""
,
MetaFactory
:
DefaultMetaFactory
,
MetaFactory
:
DefaultMetaFactory
,
}
}
s
.
converter
.
N
ameFunc
=
s
.
nameFunc
s
.
converter
.
n
ameFunc
=
s
.
nameFunc
return
s
return
s
}
}
...
@@ -194,7 +194,7 @@ func (s *Scheme) NewObject(versionName, kind string) (interface{}, error) {
...
@@ -194,7 +194,7 @@ func (s *Scheme) NewObject(versionName, kind string) (interface{}, error) {
// add conversion functions for things with changed/removed fields.
// add conversion functions for things with changed/removed fields.
func
(
s
*
Scheme
)
AddConversionFuncs
(
conversionFuncs
...
interface
{})
error
{
func
(
s
*
Scheme
)
AddConversionFuncs
(
conversionFuncs
...
interface
{})
error
{
for
_
,
f
:=
range
conversionFuncs
{
for
_
,
f
:=
range
conversionFuncs
{
if
err
:=
s
.
converter
.
Register
(
f
);
err
!=
nil
{
if
err
:=
s
.
converter
.
Register
ConversionFunc
(
f
);
err
!=
nil
{
return
err
return
err
}
}
}
}
...
@@ -209,6 +209,29 @@ func (s *Scheme) AddStructFieldConversion(srcFieldType interface{}, srcFieldName
...
@@ -209,6 +209,29 @@ func (s *Scheme) AddStructFieldConversion(srcFieldType interface{}, srcFieldName
return
s
.
converter
.
SetStructFieldCopy
(
srcFieldType
,
srcFieldName
,
destFieldType
,
destFieldName
)
return
s
.
converter
.
SetStructFieldCopy
(
srcFieldType
,
srcFieldName
,
destFieldType
,
destFieldName
)
}
}
// AddDefaultingFuncs adds functions to the list of default-value functions.
// Each of the given functions is responsible for applying default values
// when converting an instance of a versioned API object into an internal
// API object. These functions do not need to handle sub-objects. We deduce
// how to call these functions from the types of their two parameters.
//
// s.AddDefaultingFuncs(
// func(obj *v1beta1.Pod) {
// if obj.OptionalField == "" {
// obj.OptionalField = "DefaultValue"
// }
// },
// )
func
(
s
*
Scheme
)
AddDefaultingFuncs
(
defaultingFuncs
...
interface
{})
error
{
for
_
,
f
:=
range
defaultingFuncs
{
err
:=
s
.
converter
.
RegisterDefaultingFunc
(
f
)
if
err
!=
nil
{
return
err
}
}
return
nil
}
// Convert will attempt to convert in into out. Both must be pointers. For easy
// Convert will attempt to convert in into out. Both must be pointers. For easy
// testing of conversion functions. Returns an error if the conversion isn't
// testing of conversion functions. Returns an error if the conversion isn't
// possible. You can call this with types that haven't been registered (for example,
// possible. You can call this with types that haven't been registered (for example,
...
...
pkg/runtime/scheme.go
View file @
1ddb68d8
...
@@ -265,7 +265,8 @@ func (s *Scheme) Log(l conversion.DebugLogger) {
...
@@ -265,7 +265,8 @@ func (s *Scheme) Log(l conversion.DebugLogger) {
// AddConversionFuncs adds a function to the list of conversion functions. The given
// AddConversionFuncs adds a function to the list of conversion functions. The given
// function should know how to convert between two API objects. We deduce how to call
// function should know how to convert between two API objects. We deduce how to call
// it from the types of its two parameters; see the comment for Converter.Register.
// it from the types of its two parameters; see the comment for
// Converter.RegisterConversionFunction.
//
//
// Note that, if you need to copy sub-objects that didn't change, it's safe to call
// Note that, if you need to copy sub-objects that didn't change, it's safe to call
// Convert() inside your conversionFuncs, as long as you don't start a conversion
// Convert() inside your conversionFuncs, as long as you don't start a conversion
...
@@ -287,6 +288,13 @@ func (s *Scheme) AddStructFieldConversion(srcFieldType interface{}, srcFieldName
...
@@ -287,6 +288,13 @@ func (s *Scheme) AddStructFieldConversion(srcFieldType interface{}, srcFieldName
return
s
.
raw
.
AddStructFieldConversion
(
srcFieldType
,
srcFieldName
,
destFieldType
,
destFieldName
)
return
s
.
raw
.
AddStructFieldConversion
(
srcFieldType
,
srcFieldName
,
destFieldType
,
destFieldName
)
}
}
// AddDefaultingFuncs adds a function to the list of value-defaulting functions.
// We deduce how to call it from the types of its two parameters; see the
// comment for Converter.RegisterDefaultingFunction.
func
(
s
*
Scheme
)
AddDefaultingFuncs
(
defaultingFuncs
...
interface
{})
error
{
return
s
.
raw
.
AddDefaultingFuncs
(
defaultingFuncs
...
)
}
// Convert will attempt to convert in into out. Both must be pointers.
// Convert will attempt to convert in into out. Both must be pointers.
// For easy testing of conversion functions. Returns an error if the conversion isn't
// For easy testing of conversion functions. Returns an error if the conversion isn't
// possible.
// possible.
...
...
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