diff --git a/lib/majic/extension.ex b/lib/majic/extension.ex index 4a503fc76cc0a49af65c4a3713285edfa3f2a70a..07cfc208a34fc7bc4c381f6ae4d7147e89c60dee 100644 --- a/lib/majic/extension.ex +++ b/lib/majic/extension.ex @@ -59,29 +59,47 @@ defmodule Majic.Extension do defp do_fix(name, mime_type, options) do append? = Keyword.get(options, :append, false) subtype? = Keyword.get(options, :subtype_as_extension, false) - exts = MIME.extensions(mime_type) ++ subtype_extension(subtype?, mime_type) + ext_candidates = MIME.extensions(mime_type) old_ext = String.downcase(Path.extname(name)) + old_ext_bare = String.trim_leading(old_ext, ".") + basename = Path.basename(name, old_ext) - unless old_ext == "" do - basename = Path.basename(name, old_ext) - "." <> old = old_ext - - if old in exts do - Enum.join([basename, ".", old]) - else - ext = List.first(exts) - - ext_list = - cond do - ext && append? -> [old, ext] - !ext -> [] - ext -> [ext] - end - - Enum.join([basename] ++ ext_list, ".") - end - else - name + cond do + # extension already in candidate list, so no-op + old_ext_bare in ext_candidates -> + name + + # has extension, append the subtype + not match?("", old_ext) && append? && subtype? -> + Enum.join([name, subtype_extension(subtype?, mime_type)], ".") + + # has extension, change to subtype + not match?("", old_ext) && subtype? -> + Enum.join([basename, subtype_extension(subtype?, mime_type)], ".") + + # no extension, append + match?("", old_ext) && append? -> + Enum.join([basename, List.first(ext_candidates)], ".") + + # no candidates, so strip extension + match?([], ext_candidates) -> + basename + + # no extension but no appending, so no-op + match?("", old_ext) -> + name + + # append first candidate + not Enum.empty?(ext_candidates) && append? -> + Enum.join([name, List.first(ext_candidates)], ".") + + # change extension to first candidate + not Enum.empty?(ext_candidates) -> + Enum.join([basename, List.first(ext_candidates)], ".") + + # do nothing + true -> + name end end diff --git a/test/majic/extension_test.exs b/test/majic/extension_test.exs index 2e375a1265f33cb267d17c595b89cbafec79fa7d..be9c644dbf6cdbcdbd811bbbb976c7fa8f8cbb93 100644 --- a/test/majic/extension_test.exs +++ b/test/majic/extension_test.exs @@ -13,6 +13,14 @@ defmodule Majic.ExtensionTest do assert "cat.jpeg.webp" == Extension.fix("cat.jpeg", "image/webp", append: true) end + test "it appends extensions if none exist" do + assert "webpage.html" == Extension.fix("webpage", "text/html", append: true) + end + + test "it does not append extension if none exist when appending not requested" do + assert "webpage" == Extension.fix("webpage", "text/html") + end + test "it uses subtype as extension" do assert "Makefile.x-makefile" == Extension.fix("Makefile.txt", "text/x-makefile", subtype_as_extension: true)