       {ptr, acc} = decode_data_ptr(acc)
       <<type, acc :: binary>> = acc
 
-      {map_key(key: key, data_type: int_to_type(type), data_ptr: ptr), acc}
+      {field(name: key, type: int_to_type(type), ptr: ptr), acc}
     end
   end
 
   defp decode_map_values(data, keys, schema) do
-    Enum.map_reduce keys, data, fn(map_key(key: key_name, data_type: type, data_ptr: ptr), acc) ->
-      if ptr == 0 do
-        {{key_name, nil}, acc}
-      else
-        {value, acc} = decode_type(acc, type, schema)
-        {{key_name, value}, acc}
-      end
-    end
+    Enum.map_reduce(keys, data, &decode_field(&2, &1, schema))
   end
 
   defp encode_fields(%{} = fields, offset) do

  end

  def decode_type(data, :decimal, _) do
    <<scale :: 32, value_size :: 32, rest :: binary>> = data
    nbits = value_size * 8
    <<value :: size(nbits)-big, rest :: binary>> = rest

    value = value / round(:math.pow(10, scale))
    {Decimal.new(value), rest}


  def decode_type(data, :link_list, _) do
    {nelems, rest} = :small_ints.decode_zigzag_varint(data)
    {elems, rest} = Enum.map_reduce List.duplicate(nil, nelems), rest, fn(_, acc) ->
      decode_type(acc, :link)
    end

