mirror of
https://github.com/genuinetools/reg.git
synced 2024-09-17 16:11:01 -04:00
64 lines
1.5 KiB
Go
64 lines
1.5 KiB
Go
|
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
|
||
|
}
|