1// Package easyjson contains marshaler/unmarshaler interfaces and helper functions.
2package easyjson
3
4import (
5	"io"
6	"io/ioutil"
7	"net/http"
8	"strconv"
9
10	"github.com/mailru/easyjson/jlexer"
11	"github.com/mailru/easyjson/jwriter"
12)
13
14// Marshaler is an easyjson-compatible marshaler interface.
15type Marshaler interface {
16	MarshalEasyJSON(w *jwriter.Writer)
17}
18
19// Marshaler is an easyjson-compatible unmarshaler interface.
20type Unmarshaler interface {
21	UnmarshalEasyJSON(w *jlexer.Lexer)
22}
23
24// Optional defines an undefined-test method for a type to integrate with 'omitempty' logic.
25type Optional interface {
26	IsDefined() bool
27}
28
29// Marshal returns data as a single byte slice. Method is suboptimal as the data is likely to be copied
30// from a chain of smaller chunks.
31func Marshal(v Marshaler) ([]byte, error) {
32	w := jwriter.Writer{}
33	v.MarshalEasyJSON(&w)
34	return w.BuildBytes()
35}
36
37// MarshalToWriter marshals the data to an io.Writer.
38func MarshalToWriter(v Marshaler, w io.Writer) (written int, err error) {
39	jw := jwriter.Writer{}
40	v.MarshalEasyJSON(&jw)
41	return jw.DumpTo(w)
42}
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).
48func 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
57	started = true
58	written, err = jw.DumpTo(w)
59	return
60}
61
62// Unmarshal decodes the JSON in data into the object.
63func Unmarshal(data []byte, v Unmarshaler) error {
64	l := jlexer.Lexer{Data: data}
65	v.UnmarshalEasyJSON(&l)
66	return l.Error()
67}
68
69// UnmarshalFromReader reads all the data in the reader and decodes as JSON into the object.
70func UnmarshalFromReader(r io.Reader, v Unmarshaler) error {
71	data, err := ioutil.ReadAll(r)
72	if err != nil {
73		return err
74	}
75	l := jlexer.Lexer{Data: data}
76	v.UnmarshalEasyJSON(&l)
77	return l.Error()
78}
79