helpers.go 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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. // UnknownsUnmarshaler provides a method to unmarshal unknown struct fileds and save them as you want
  24. type UnknownsUnmarshaler interface {
  25. UnmarshalUnknown(in *jlexer.Lexer, key string)
  26. }
  27. // UnknownsMarshaler provides a method to write additional struct fields
  28. type UnknownsMarshaler interface {
  29. MarshalUnknowns(w *jwriter.Writer, first bool)
  30. }
  31. // Marshal returns data as a single byte slice. Method is suboptimal as the data is likely to be copied
  32. // from a chain of smaller chunks.
  33. func Marshal(v Marshaler) ([]byte, error) {
  34. w := jwriter.Writer{}
  35. v.MarshalEasyJSON(&w)
  36. return w.BuildBytes()
  37. }
  38. // MarshalToWriter marshals the data to an io.Writer.
  39. func MarshalToWriter(v Marshaler, w io.Writer) (written int, err error) {
  40. jw := jwriter.Writer{}
  41. v.MarshalEasyJSON(&jw)
  42. return jw.DumpTo(w)
  43. }
  44. // MarshalToHTTPResponseWriter sets Content-Length and Content-Type headers for the
  45. // http.ResponseWriter, and send the data to the writer. started will be equal to
  46. // false if an error occurred before any http.ResponseWriter methods were actually
  47. // invoked (in this case a 500 reply is possible).
  48. func MarshalToHTTPResponseWriter(v Marshaler, w http.ResponseWriter) (started bool, written int, err error) {
  49. jw := jwriter.Writer{}
  50. v.MarshalEasyJSON(&jw)
  51. if jw.Error != nil {
  52. return false, 0, jw.Error
  53. }
  54. w.Header().Set("Content-Type", "application/json")
  55. w.Header().Set("Content-Length", strconv.Itoa(jw.Size()))
  56. started = true
  57. written, err = jw.DumpTo(w)
  58. return
  59. }
  60. // Unmarshal decodes the JSON in data into the object.
  61. func Unmarshal(data []byte, v Unmarshaler) error {
  62. l := jlexer.Lexer{Data: data}
  63. v.UnmarshalEasyJSON(&l)
  64. return l.Error()
  65. }
  66. // UnmarshalFromReader reads all the data in the reader and decodes as JSON into the object.
  67. func UnmarshalFromReader(r io.Reader, v Unmarshaler) error {
  68. data, err := ioutil.ReadAll(r)
  69. if err != nil {
  70. return err
  71. }
  72. l := jlexer.Lexer{Data: data}
  73. v.UnmarshalEasyJSON(&l)
  74. return l.Error()
  75. }