|
149 | 149 |
|
150 | 150 | defimpl JSON.Encoder, for: Map do
|
151 | 151 | def encode(value, encoder) do
|
152 |
| - :elixir_json.encode_map(value, encoder) |
| 152 | + case :maps.next(:maps.iterator(value)) do |
| 153 | + :none -> |
| 154 | + "{}" |
| 155 | + |
| 156 | + {key, value, iterator} -> |
| 157 | + [?{, key(key, encoder), ?:, encoder.(value, encoder) | next(iterator, encoder)] |
| 158 | + end |
153 | 159 | end
|
| 160 | + |
| 161 | + defp next(iterator, encoder) do |
| 162 | + case :maps.next(iterator) do |
| 163 | + :none -> |
| 164 | + "}" |
| 165 | + |
| 166 | + {key, value, iterator} -> |
| 167 | + [?,, key(key, encoder), ?:, encoder.(value, encoder) | next(iterator, encoder)] |
| 168 | + end |
| 169 | + end |
| 170 | + |
| 171 | + # Erlang supports only numbers, binaries, and atoms as keys, |
| 172 | + # we support anything that implements the String.Chars protocol. |
| 173 | + defp key(key, encoder) when is_atom(key), do: encoder.(Atom.to_string(key), encoder) |
| 174 | + defp key(key, encoder) when is_binary(key), do: encoder.(key, encoder) |
| 175 | + defp key(key, encoder), do: encoder.(String.Chars.to_string(key), encoder) |
154 | 176 | end
|
155 | 177 |
|
156 | 178 | defimpl JSON.Encoder, for: Duration do
|
@@ -262,17 +284,15 @@ defmodule JSON do
|
262 | 284 |
|
263 | 285 | Elixir primitive types are encoded to JSON as follows:
|
264 | 286 |
|
265 |
| - | **Elixir** | **JSON** | |
266 |
| - |------------------------|----------| |
267 |
| - | `integer() \| float()` | Number | |
268 |
| - | `true \| false ` | Boolean | |
269 |
| - | `nil` | Null | |
270 |
| - | `binary()` | String | |
271 |
| - | `atom()` | String | |
272 |
| - | `list()` | Array | |
273 |
| - | `%{binary() => _}` | Object | |
274 |
| - | `%{atom() => _}` | Object | |
275 |
| - | `%{integer() => _}` | Object | |
| 287 | + | **Elixir** | **JSON** | |
| 288 | + |----------------------------|----------| |
| 289 | + | `integer() \| float()` | Number | |
| 290 | + | `true \| false ` | Boolean | |
| 291 | + | `nil` | Null | |
| 292 | + | `binary()` | String | |
| 293 | + | `atom()` | String | |
| 294 | + | `list()` | Array | |
| 295 | + | `%{String.Chars.t() => _}` | Object | |
276 | 296 |
|
277 | 297 | You may also implement the `JSON.Encoder` protocol for custom data structures.
|
278 | 298 | Some built-in data-structures already derive the `JSON.Encoder` protocol:
|
@@ -499,7 +519,7 @@ defmodule JSON do
|
499 | 519 | do: :elixir_json.encode_list(value, encoder)
|
500 | 520 |
|
501 | 521 | def protocol_encode(%{} = value, encoder) when not is_map_key(value, :__struct__),
|
502 |
| - do: :elixir_json.encode_map(value, encoder) |
| 522 | + do: JSON.Encoder.Map.encode(value, encoder) |
503 | 523 |
|
504 | 524 | def protocol_encode(value, encoder),
|
505 | 525 | do: JSON.Encoder.encode(value, encoder)
|
|
0 commit comments