helpers.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. // Package easyjson contains marshaler/unmarshaler interfaces and helper functions.
  2. package easyjson
  3. import (
  4. "io"
  5. "io/ioutil"
  6. "net/http"
  7. "strconv"
  8. "github.com/mailru/easyjson/jlexer"
  9. "github.com/mailru/easyjson/jwriter"
  10. )
  11. // Marshaler is an easyjson-compatible marshaler interface.
  12. type Marshaler interface {
  13. MarshalEasyJSON(w *jwriter.Writer)
  14. }
  15. // Marshaler is an easyjson-compatible unmarshaler interface.
  16. type Unmarshaler interface {
  17. UnmarshalEasyJSON(w *jlexer.Lexer)
  18. }
  19. // Optional defines an undefined-test method for a type to integrate with 'omitempty' logic.
  20. type Optional interface {
  21. IsDefined() bool
  22. }
  23. // Marshal returns data as a single byte slice. Method is suboptimal as the data is likely to be copied
  24. // from a chain of smaller chunks.
  25. func Marshal(v Marshaler) ([]byte, error) {
  26. w := jwriter.Writer{}
  27. v.MarshalEasyJSON(&w)
  28. return w.BuildBytes()
  29. }
  30. // MarshalToWriter marshals the data to an io.Writer.
  31. func MarshalToWriter(v Marshaler, w io.Writer) (written int, err error) {
  32. jw := jwriter.Writer{}
  33. v.MarshalEasyJSON(&jw)
  34. return jw.DumpTo(w)
  35. }
  36. // MarshalToHTTPResponseWriter sets Content-Length and Content-Type headers for the
  37. // http.ResponseWriter, and send the data to the writer. started will be equal to
  38. // false if an error occurred before any http.ResponseWriter methods were actually
  39. // invoked (in this case a 500 reply is possible).
  40. func MarshalToHTTPResponseWriter(v Marshaler, w http.ResponseWriter) (started bool, written int, err error) {
  41. jw := jwriter.Writer{}
  42. v.MarshalEasyJSON(&jw)
  43. if jw.Error != nil {
  44. return false, 0, jw.Error
  45. }
  46. w.Header().Set("Content-Type", "application/json")
  47. w.Header().Set("Content-Length", strconv.Itoa(jw.Size()))
  48. started = true
  49. written, err = jw.DumpTo(w)
  50. return
  51. }
  52. // Unmarshal decodes the JSON in data into the object.
  53. func Unmarshal(data []byte, v Unmarshaler) error {
  54. l := jlexer.Lexer{Data: data}
  55. v.UnmarshalEasyJSON(&l)
  56. return l.Error()
  57. }
  58. // UnmarshalFromReader reads all the data in the reader and decodes as JSON into the object.
  59. func UnmarshalFromReader(r io.Reader, v Unmarshaler) error {
  60. data, err := ioutil.ReadAll(r)
  61. if err != nil {
  62. return err
  63. }
  64. l := jlexer.Lexer{Data: data}
  65. v.UnmarshalEasyJSON(&l)
  66. return l.Error()
  67. }