     end
   end
 
-  def decodable?(env, opts), do: decodable_body?(env) && decodable_content_type?(env, opts)
+  defp decodable?(env, opts), do: decodable_body?(env) && decodable_content_type?(env, opts)
 
-  def decodable_body?(env) do
+  defp decodable_body?(env) do
     (is_binary(env.body)  && env.body != "") ||
     (is_list(env.body)    && env.body != [])
   end
 
-  def decodable_content_type?(env, opts) do
+  defp decodable_content_type?(env, opts) do
     case env.headers["content-type"] do
       nil           -> false
       content_type  -> Enum.any?(content_types(opts), &String.starts_with?(content_type, &1))
     end
   end
 
-  def content_types(opts), do: @default_content_types ++ Keyword.get(opts, :decode_content_types, [])
+  defp content_types(opts), do: @default_content_types ++ Keyword.get(opts, :decode_content_types, [])
 
   defp process(data, op, opts) do
     with {:ok, value} <- do_process(data, op, opts) do

    Stream.map body, fn item -> encode_body(item, opts) <> "\n" end
  end

  def encodable?(%{body: nil}),                 do: false
  def encodable?(%{body: %Tesla.Multipart{}}),  do: false
  def encodable?(_),                            do: true

  def decode(env, opts) do
    if decodable?(env, opts) do
      Map.update!(env, :body, &process(&1, :decode, opts))

    |> decode(opts)
  end

  @doc """
  Encode request body as JSON. Used by `Tesla.Middleware.EncodeJson`
  """
  def encode(env, opts) do
    if encodable?(env) do
      env
