@@ -84,7 +84,7 @@ defmodule BSON.Encoder do
84
84
do: encode ( Atom . to_string ( value ) )
85
85
86
86
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 ]
88
88
89
89
def encode ( value ) when is_float ( value ) ,
90
90
do: << value :: little - float64 >>
@@ -98,18 +98,32 @@ defmodule BSON.Encoder do
98
98
def document ( doc ) do
99
99
{ _ , iodata } =
100
100
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
+
105
113
{ key , value } , { _ , acc } ->
106
114
{ key_type , key } = key ( key )
107
115
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
+
109
123
{ key_type , [ acc , type , key , value ] }
110
124
end )
111
125
112
- [ << IO . iodata_length ( iodata ) + 5 :: int32 >> , iodata , 0x00 ]
126
+ [ << IO . iodata_length ( iodata ) + 5 :: int32 >> , iodata , 0x00 ]
113
127
end
114
128
115
129
defp cstring ( string ) , do: [ string , 0x00 ]
@@ -119,44 +133,45 @@ defmodule BSON.Encoder do
119
133
120
134
defp array ( [ ] , _ix ) ,
121
135
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 ) ]
124
139
125
140
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 ) } "
127
142
raise ArgumentError , message
128
143
end
129
144
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
157
172
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
161
176
defp subtype ( int ) when is_integer ( int ) and int in 0x80 .. 0xFF , do: 0x80
162
177
end
0 commit comments