Import upstream version 0.0~git20220921.a4b6fa1
Debian Janitor
1 year, 4 months ago
49 | 49 |
* field name become member name;
|
50 | 50 |
* if field has xmlrpc tag, its value become member name.
|
51 | 51 |
* for fields tagged with `",omitempty"`, empty values are omitted;
|
|
52 |
* fields tagged with `"-"` are omitted.
|
52 | 53 |
|
53 | 54 |
Server method can accept few arguments, to handle this case there is
|
54 | 55 |
special approach to handle slice of empty interfaces (`[]interface{}`).
|
148 | 148 |
fieldVal := val.FieldByName(field.Name)
|
149 | 149 |
|
150 | 150 |
if fieldVal.CanSet() {
|
151 | |
if fn := field.Tag.Get("xmlrpc"); fn != "" {
|
152 | |
fields[fn] = fieldVal
|
153 | |
} else {
|
154 | |
fields[field.Name] = fieldVal
|
|
151 |
name := field.Tag.Get("xmlrpc")
|
|
152 |
name = strings.TrimSuffix(name, ",omitempty")
|
|
153 |
if name == "-" {
|
|
154 |
continue
|
155 | 155 |
}
|
|
156 |
if name == "" {
|
|
157 |
name = field.Name
|
|
158 |
}
|
|
159 |
fields[name] = fieldVal
|
156 | 160 |
}
|
157 | 161 |
}
|
158 | 162 |
} else {
|
94 | 94 |
fieldType := structType.Field(i)
|
95 | 95 |
|
96 | 96 |
name := fieldType.Tag.Get("xmlrpc")
|
|
97 |
// skip ignored fields.
|
|
98 |
if name == "-" {
|
|
99 |
continue
|
|
100 |
}
|
97 | 101 |
// if the tag has the omitempty property, skip it
|
98 | |
if strings.HasSuffix(name, ",omitempty") && isZero(fieldVal) {
|
|
102 |
if strings.HasSuffix(name, ",omitempty") && fieldVal.IsZero() {
|
99 | 103 |
continue
|
100 | 104 |
}
|
101 | 105 |
name = strings.TrimSuffix(name, ",omitempty")
|
54 | 54 |
}, "<value><struct><member><name>Title</name><value><string>War and Piece</string></value></member><member><name>Amount</name><value><int>20</int></value></member><member><name>author</name><value><string>Leo Tolstoy</string></value></member></struct></value>"},
|
55 | 55 |
{&struct {
|
56 | 56 |
}{}, "<value><struct></struct></value>"},
|
|
57 |
{&struct {
|
|
58 |
ID int `xmlrpc:"id"`
|
|
59 |
Name string `xmlrpc:"-"`
|
|
60 |
}{
|
|
61 |
ID: 123, Name: "kolo",
|
|
62 |
}, "<value><struct><member><name>id</name><value><int>123</int></value></member></struct></value>"},
|
57 | 63 |
}
|
58 | 64 |
|
59 | 65 |
func Test_marshal(t *testing.T) {
|
|
0 |
module github.com/kolo/xmlrpc
|
|
1 |
|
|
2 |
go 1.14
|
|
3 |
|
|
4 |
require golang.org/x/text v0.3.3
|
|
0 |
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
|
1 |
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
2 |
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
0 | |
package xmlrpc
|
1 | |
|
2 | |
import (
|
3 | |
"math"
|
4 | |
. "reflect"
|
5 | |
)
|
6 | |
|
7 | |
func isZero(v Value) bool {
|
8 | |
switch v.Kind() {
|
9 | |
case Bool:
|
10 | |
return !v.Bool()
|
11 | |
case Int, Int8, Int16, Int32, Int64:
|
12 | |
return v.Int() == 0
|
13 | |
case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
|
14 | |
return v.Uint() == 0
|
15 | |
case Float32, Float64:
|
16 | |
return math.Float64bits(v.Float()) == 0
|
17 | |
case Complex64, Complex128:
|
18 | |
c := v.Complex()
|
19 | |
return math.Float64bits(real(c)) == 0 && math.Float64bits(imag(c)) == 0
|
20 | |
case Array:
|
21 | |
for i := 0; i < v.Len(); i++ {
|
22 | |
if !isZero(v.Index(i)) {
|
23 | |
return false
|
24 | |
}
|
25 | |
}
|
26 | |
return true
|
27 | |
case Chan, Func, Interface, Map, Ptr, Slice, UnsafePointer:
|
28 | |
return v.IsNil()
|
29 | |
case String:
|
30 | |
return v.Len() == 0
|
31 | |
case Struct:
|
32 | |
for i := 0; i < v.NumField(); i++ {
|
33 | |
if !isZero(v.Field(i)) {
|
34 | |
return false
|
35 | |
}
|
36 | |
}
|
37 | |
return true
|
38 | |
default:
|
39 | |
// This should never happens, but will act as a safeguard for
|
40 | |
// later, as a default value doesn't makes sense here.
|
41 | |
panic(&ValueError{"reflect.Value.IsZero", v.Kind()})
|
42 | |
}
|
43 | |
}
|