backend.ex (2422B)
1 require Logger 2 3 defmodule FileSystem.Backend do 4 @moduledoc """ 5 FileSystem Backend Behaviour. 6 """ 7 8 @callback bootstrap() :: :ok | {:error, atom()} 9 @callback supported_systems() :: [{atom(), atom()}] 10 @callback known_events() :: [atom()] 11 12 @doc """ 13 Get and validate backend module, return `{:ok, backend_module}` when success and 14 return `{:error, reason}` when fail. 15 When `nil` is given, will return default backend by os. 16 When a custom module is given, make sure `start_link/1`, `bootstrap/0` and 17 `supported_system/0` are defnied. 18 """ 19 @spec backend(atom) :: {:ok, atom()} | {:error, atom()} 20 def backend(backend) do 21 with {:ok, module} <- backend_module(backend), 22 :ok <- validate_os(backend, module), 23 :ok <- module.bootstrap 24 do 25 {:ok, module} 26 else 27 {:error, reason} -> {:error, reason} 28 end 29 end 30 31 defp backend_module(nil) do 32 case :os.type() do 33 {:unix, :darwin} -> :fs_mac 34 {:unix, :linux} -> :fs_inotify 35 {:unix, :freebsd} -> :fs_inotify 36 {:unix, :openbsd} -> :fs_inotify 37 {:win32, :nt} -> :fs_windows 38 system -> {:unsupported_system, system} 39 end |> backend_module 40 end 41 defp backend_module(:fs_mac), do: {:ok, FileSystem.Backends.FSMac} 42 defp backend_module(:fs_inotify), do: {:ok, FileSystem.Backends.FSInotify} 43 defp backend_module(:fs_windows), do: {:ok, FileSystem.Backends.FSWindows} 44 defp backend_module(:fs_poll), do: {:ok, FileSystem.Backends.FSPoll} 45 defp backend_module({:unsupported_system, system}) do 46 Logger.error "I'm so sorry but `file_system` does NOT support your current system #{inspect system} for now." 47 {:error, :unsupported_system} 48 end 49 defp backend_module(module) do 50 functions = module.__info__(:functions) 51 {:start_link, 1} in functions && 52 {:bootstrap, 0} in functions && 53 {:supported_systems, 0} in functions || 54 raise "illegal backend" 55 rescue 56 _ -> 57 Logger.error "You are using custom backend `#{inspect module}`, make sure it's a legal file_system backend module." 58 {:error, :illegal_backend} 59 end 60 61 defp validate_os(backend, module) do 62 os_type = :os.type() 63 if os_type in module.supported_systems() do 64 :ok 65 else 66 Logger.error "The backend `#{backend}` you are using does NOT support your current system #{inspect os_type}." 67 {:error, :unsupported_system} 68 end 69 end 70 end