@@ -3,57 +3,31 @@ defprotocol JSON.Encoder do
33 A protocol for custom JSON encoding of data structures.
44 """
55
6- @ fallback_to_any true
6+ @ undefined_impl_description """
7+ the protocol must be explicitly implemented.
78
8- @ doc """
9- A function invoked to encode the given term.
10- """
11- def encode ( term , encoder )
12- end
9+ If you have a struct, you can derive the implementation specifying \
10+ which fields should be encoded to JSON:
1311
14- defimpl JSON.Encoder , for: Atom do
15- def encode ( value , encoder ) do
16- case value do
17- nil -> "null"
18- true -> "true"
19- false -> "false"
20- _ -> encoder . ( Atom . to_string ( value ) , encoder )
21- end
22- end
23- end
12+ @derive {JSON.Encoder, only: [....]}
13+ defstruct ...
2414
25- defimpl JSON.Encoder , for: BitString do
26- def encode ( value , _encoder ) do
27- :elixir_json . encode_binary ( value )
28- end
29- end
15+ It is also possible to encode all fields, although this should be \
16+ used carefully to avoid accidentally leaking private information \
17+ when new fields are added:
3018
31- defimpl JSON.Encoder , for: List do
32- def encode ( value , encoder ) do
33- :elixir_json . encode_list ( value , encoder )
34- end
35- end
36-
37- defimpl JSON.Encoder , for: Integer do
38- def encode ( value , _encoder ) do
39- :elixir_json . encode_integer ( value )
40- end
41- end
19+ @derive JSON.Encoder
20+ defstruct ...
4221
43- defimpl JSON.Encoder , for: Float do
44- def encode ( value , _encoder ) do
45- :elixir_json . encode_float ( value )
46- end
47- end
22+ Finally, if you don't own the struct you want to encode to JSON, \
23+ you may use Protocol.derive/3 placed outside of any module:
4824
49- defimpl JSON.Encoder , for: Map do
50- def encode ( value , encoder ) do
51- :elixir_json . encode_map ( value , encoder )
52- end
53- end
25+ Protocol.derive(JSON.Encoder, NameOfTheStruct, only: [...])
26+ Protocol.derive(JSON.Encoder, NameOfTheStruct)\
27+ """
5428
55- defimpl JSON.Encoder , for: Any do
56- defmacro __deriving__ ( module , _struct , opts ) do
29+ @ impl true
30+ defmacro __deriving__ ( module , opts ) do
5731 fields = module |> Macro . struct_info! ( __CALLER__ ) |> Enum . map ( & & 1 . field )
5832 fields = fields_to_encode ( fields , opts )
5933 vars = Macro . generate_arguments ( length ( fields ) , __MODULE__ )
@@ -105,38 +79,50 @@ defimpl JSON.Encoder, for: Any do
10579 end
10680 end
10781
108- def encode ( % _ { } = struct , _encoder ) do
109- raise Protocol.UndefinedError ,
110- protocol: @ protocol ,
111- value: struct ,
112- description: """
113- JSON.Encoder protocol must be explicitly implemented for structs
114-
115- If you own the struct, you can derive the implementation specifying \
116- which fields should be encoded to JSON:
117-
118- @derive {JSON.Encoder, only: [....]}
119- defstruct ...
82+ @ doc """
83+ A function invoked to encode the given term.
84+ """
85+ def encode ( term , encoder )
86+ end
12087
121- It is also possible to encode all fields, although this should be \
122- used carefully to avoid accidentally leaking private information \
123- when new fields are added:
88+ defimpl JSON.Encoder , for: Atom do
89+ def encode ( value , encoder ) do
90+ case value do
91+ nil -> "null"
92+ true -> "true"
93+ false -> "false"
94+ _ -> encoder . ( Atom . to_string ( value ) , encoder )
95+ end
96+ end
97+ end
12498
125- @derive JSON.Encoder
126- defstruct ...
99+ defimpl JSON.Encoder , for: BitString do
100+ def encode ( value , _encoder ) do
101+ :elixir_json . encode_binary ( value )
102+ end
103+ end
127104
128- Finally, if you don't own the struct you want to encode to JSON, \
129- you may use Protocol.derive/3 placed outside of any module:
105+ defimpl JSON.Encoder , for: List do
106+ def encode ( value , encoder ) do
107+ :elixir_json . encode_list ( value , encoder )
108+ end
109+ end
130110
131- Protocol.derive( JSON.Encoder, NameOfTheStruct, only: [...])
132- Protocol.derive(JSON.Encoder, NameOfTheStruct)
133- """
111+ defimpl JSON.Encoder , for: Integer do
112+ def encode ( value , _encoder ) do
113+ :elixir_json . encode_integer ( value )
134114 end
115+ end
135116
117+ defimpl JSON.Encoder , for: Float do
136118 def encode ( value , _encoder ) do
137- raise Protocol.UndefinedError ,
138- protocol: @ protocol ,
139- value: value
119+ :elixir_json . encode_float ( value )
120+ end
121+ end
122+
123+ defimpl JSON.Encoder , for: Map do
124+ def encode ( value , encoder ) do
125+ :elixir_json . encode_map ( value , encoder )
140126 end
141127end
142128
0 commit comments