Skip to content

Commit b18f424

Browse files
committed
Merge remote-tracking branch 'origin/master'
2 parents 43d504c + df4bd53 commit b18f424

File tree

8 files changed

+799
-459
lines changed

8 files changed

+799
-459
lines changed

README.md

Lines changed: 108 additions & 61 deletions
Large diffs are not rendered by default.

lib/bson/encoder.ex

Lines changed: 55 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ defmodule BSON.Encoder do
8484
do: encode(Atom.to_string(value))
8585

8686
def encode(value) when is_binary(value),
87-
do: [<<byte_size(value)+1::int32>>, value, 0x00]
87+
do: [<<byte_size(value) + 1::int32>>, value, 0x00]
8888

8989
def encode(value) when is_float(value),
9090
do: <<value::little-float64>>
@@ -98,18 +98,32 @@ defmodule BSON.Encoder do
9898
def document(doc) do
9999
{_, iodata} =
100100
Enum.reduce(doc, {:unknown, ""}, fn
101-
{:__struct__, _value}, {:binary, _acc} -> invalid_doc(doc)
102-
{:__struct__, _value}, {_, acc} -> {:atom, acc}
103-
{key, _value}, {:binary, _acc} when is_atom(key) -> invalid_doc(doc)
104-
{key, _value}, {:atom, _acc} when is_binary(key) -> invalid_doc(doc)
101+
{:__struct__, _value}, {:binary, _acc} ->
102+
invalid_doc(doc)
103+
104+
{:__struct__, _value}, {_, acc} ->
105+
{:atom, acc}
106+
107+
{key, _value}, {:binary, _acc} when is_atom(key) ->
108+
invalid_doc(doc)
109+
110+
{key, _value}, {:atom, _acc} when is_binary(key) ->
111+
invalid_doc(doc)
112+
105113
{key, value}, {_, acc} ->
106114
{key_type, key} = key(key)
107115
type = type(value)
108-
value = encode(value)
116+
117+
value =
118+
case Mongo.Encoder.impl_for(value) do
119+
nil -> encode(value)
120+
_ -> value |> Mongo.Encoder.encode() |> encode()
121+
end
122+
109123
{key_type, [acc, type, key, value]}
110124
end)
111125

112-
[<<IO.iodata_length(iodata)+5::int32>>, iodata, 0x00]
126+
[<<IO.iodata_length(iodata) + 5::int32>>, iodata, 0x00]
113127
end
114128

115129
defp cstring(string), do: [string, 0x00]
@@ -119,44 +133,45 @@ defmodule BSON.Encoder do
119133

120134
defp array([], _ix),
121135
do: []
122-
defp array([hd|tl], ix) when not is_tuple(hd),
123-
do: [{Integer.to_string(ix), hd} | array(tl, ix+1)]
136+
137+
defp array([hd | tl], ix) when not is_tuple(hd),
138+
do: [{Integer.to_string(ix), hd} | array(tl, ix + 1)]
124139

125140
defp invalid_doc(doc) do
126-
message = "invalid document containing atom and string keys: #{inspect doc}"
141+
message = "invalid document containing atom and string keys: #{inspect(doc)}"
127142
raise ArgumentError, message
128143
end
129144

130-
defp type(%BSON.Binary{}), do: @type_binary
131-
defp type(%BSON.ObjectId{}), do: @type_objectid
132-
defp type(%DateTime{}), do: @type_datetime
133-
defp type(%BSON.Regex{}), do: @type_regex
134-
defp type(%BSON.JavaScript{scope: nil}), do: @type_js
135-
defp type(%BSON.JavaScript{}), do: @type_js_scope
136-
defp type(%BSON.Timestamp{}), do: @type_timestamp
137-
defp type(%BSON.LongNumber{}), do: @type_int64
138-
defp type(%Decimal{}), do: @type_decimal128
139-
defp type(nil), do: @type_null
140-
defp type(:BSON_min), do: @type_min
141-
defp type(:BSON_max), do: @type_max
142-
defp type(:inf), do: @type_float
143-
defp type(:"-inf"), do: @type_float
144-
defp type(:NaN), do: @type_float
145-
defp type(value) when is_boolean(value), do: @type_bool
146-
defp type(value) when is_float(value), do: @type_float
147-
defp type(value) when is_atom(value), do: @type_string
148-
defp type(value) when is_binary(value), do: @type_string
149-
defp type(value) when is_map(value), do: @type_document
150-
defp type([{_,_}|_]), do: @type_document
151-
defp type(value) when is_list(value), do: @type_array
152-
defp type(value) when is_int32(value), do: @type_int32
153-
defp type(value) when is_int64(value), do: @type_int64
154-
155-
defp subtype(:generic), do: 0x00
156-
defp subtype(:function), do: 0x01
145+
defp type(%BSON.Binary{}), do: @type_binary
146+
defp type(%BSON.ObjectId{}), do: @type_objectid
147+
defp type(%DateTime{}), do: @type_datetime
148+
defp type(%BSON.Regex{}), do: @type_regex
149+
defp type(%BSON.JavaScript{scope: nil}), do: @type_js
150+
defp type(%BSON.JavaScript{}), do: @type_js_scope
151+
defp type(%BSON.Timestamp{}), do: @type_timestamp
152+
defp type(%BSON.LongNumber{}), do: @type_int64
153+
defp type(%Decimal{}), do: @type_decimal128
154+
defp type(nil), do: @type_null
155+
defp type(:BSON_min), do: @type_min
156+
defp type(:BSON_max), do: @type_max
157+
defp type(:inf), do: @type_float
158+
defp type(:"-inf"), do: @type_float
159+
defp type(:NaN), do: @type_float
160+
defp type(value) when is_boolean(value), do: @type_bool
161+
defp type(value) when is_float(value), do: @type_float
162+
defp type(value) when is_atom(value), do: @type_string
163+
defp type(value) when is_binary(value), do: @type_string
164+
defp type(value) when is_map(value), do: @type_document
165+
defp type([{_, _} | _]), do: @type_document
166+
defp type(value) when is_list(value), do: @type_array
167+
defp type(value) when is_int32(value), do: @type_int32
168+
defp type(value) when is_int64(value), do: @type_int64
169+
170+
defp subtype(:generic), do: 0x00
171+
defp subtype(:function), do: 0x01
157172
defp subtype(:binary_old), do: 0x02
158-
defp subtype(:uuid_old), do: 0x03
159-
defp subtype(:uuid), do: 0x04
160-
defp subtype(:md5), do: 0x05
173+
defp subtype(:uuid_old), do: 0x03
174+
defp subtype(:uuid), do: 0x04
175+
defp subtype(:md5), do: 0x05
161176
defp subtype(int) when is_integer(int) and int in 0x80..0xFF, do: 0x80
162177
end

0 commit comments

Comments
 (0)