object_js.go 1.5 KB

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