网络媒体类型(MIME type) 是互联网通信协议中很重要的一部分,每种 MIME 类型对应着任意种文件的扩展名.
elixir 的 mime 包实现了 mime 类型和扩展名之间的转换. 让我们来看看它的实现方法.
mime.types
文件
# MIME type Extensions
application/1d-interleaved-parityfec
application/3gpdash-qoe-report+xml
application/3gpp-ims+xml
application/A2L a2l
application/activemessage
application/alto-costmap+json
application/alto-costmapfilter+json
application/alto-directory+json
application/alto-endpointcost+json
application/alto-endpointcostparams+json
application/alto-endpointprop+json
application/alto-endpointpropparams+json
application/alto-error+json
application/alto-networkmap+json
application/alto-networkmapfilter+json
application/AML aml
application/andrew-inset ez
application/applefile
application/ATF atf
application/ATFX atfx
application/ATXML atxml
application/atom+xml atom
application/atomcat+xml atomcat
application/atomdeleted+xml atomdeleted
application/atomicmail
application/atomsvc+xml atomsvc
application/auth-policy+xml apxml
application/bacnet-xdd+zip xdd
该文件中包含了一千多种 mime 类型的对应关系. 首先, 我们在编译时读取这个文件的内容:
stream = File.stream!("lib/mime.types")
mapping = Enum.flat_map(stream, fn(line) ->
if String.starts_with?(line, ["#", "\n"]) do
[]
else
[type|exts] = line |> String.strip |> String.split
[{type, exts}]
end
end)
将文件转化成了元素为 {type, exts} 的列表 mapping. 然后利用宏生成函数:
@spec mime_to_ext(String.t) :: list(String.t) | nil
defp mime_to_ext(type)
...
for {type, exts} <- mapping do
defp mime_to_ext(unquote(type)), do: unquote(exts)
end
这样, 我们就在编译时将 mime.types
文件转化成了一千多个函数, 有效地提高了运行的速度.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。