-
Notifications
You must be signed in to change notification settings - Fork 21
/
object_js.go
63 lines (59 loc) · 1.53 KB
/
object_js.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package int64support
import (
"bytes"
"encoding/json"
"fmt"
"strconv"
)
var (
_ = json.Marshaler(new(Object))
_ = json.Unmarshaler(new(Object))
)
func (o *Object) MarshalJSON() ([]byte, error) {
if o.OptionalNumber == nil {
return ([]byte)("{}"), nil
}
return ([]byte)(fmt.Sprintf("{\"optional_number\": %d}", *o.OptionalNumber)), nil
}
func (o *Object) UnmarshalJSON(b []byte) error {
var (
trim = func(v []byte) []byte { return bytes.Trim(v, " \n\r\t") }
strip = func(v []byte, first, last byte) ([]byte, error) {
x := len(v)
if x < 2 || v[0] != first || v[x-1] != last {
return nil, fmt.Errorf("failed to strip %q and %q from byte sequence", first, last)
}
return v[1 : x-1], nil
}
)
b, err := strip(trim(b), '{', '}')
if err != nil {
return err
}
// poor man parser: assume the only commas appear between JSON key-value pairs,
// and that object hierarchy is flat
for xf, f := range bytes.Split(b, ([]byte)(",")) {
parts := bytes.SplitN(f, ([]byte)(":"), 2)
if x := len(parts); x != 2 {
if xf == 0 && (x == 0 || (x == 1 && len(trim(parts[0])) == 0)) {
return nil // empty object
}
return fmt.Errorf("failed to parse field-value seperator char ':'")
}
fieldName, err := strip(trim(parts[0]), '"', '"')
if err != nil {
return err
}
if string(fieldName) != "optional_number" {
continue // ignore unknown field
}
fieldValue := trim(parts[1])
v, err := strconv.ParseInt(string(fieldValue), 10, 64)
if err != nil {
return err
}
o.OptionalNumber = &v
break
}
return nil
}