diff --git a/lib/waffle/behaviors/storage_behaviour.ex b/lib/waffle/behaviors/storage_behaviour.ex new file mode 100644 index 0000000..4c58d98 --- /dev/null +++ b/lib/waffle/behaviors/storage_behaviour.ex @@ -0,0 +1,20 @@ +defmodule Waffle.StorageBehavior do + @moduledoc """ + Defines the behavior for file storage. + + ## Callbacks + + - `put/3`: Saves a file and returns the file name or an error. + - `url/3`: Generates a URL for accessing a file. + - `delete/3`: Deletes a file and returns the result of the operation. + """ + + @callback put(definition :: atom, version :: atom, file_and_scope :: {Waffle.File.t(), any}) :: + {:ok, file_name :: String.t()} | {:error, reason :: any} + + @callback url(definition :: atom, version :: atom, file_and_scope :: {Waffle.File.t(), any}) :: + String.t() + + @callback delete(definition :: atom, version :: atom, file_and_scope :: {Waffle.File.t(), any}) :: + atom +end diff --git a/lib/waffle/storage/local.ex b/lib/waffle/storage/local.ex index 2a3c1e4..a2dda10 100644 --- a/lib/waffle/storage/local.ex +++ b/lib/waffle/storage/local.ex @@ -22,8 +22,11 @@ defmodule Waffle.Storage.Local do end """ + @behaviour Waffle.StorageBehavior + alias Waffle.Definition.Versioning + @impl true def put(definition, version, {file, scope}) do destination_path = Path.join([ definition.storage_dir_prefix(), @@ -41,6 +44,7 @@ defmodule Waffle.Storage.Local do {:ok, file.file_name} end + @impl true def url(definition, version, file_and_scope, _options \\ []) do local_path = Path.join([ definition.storage_dir(version, file_and_scope), @@ -56,6 +60,7 @@ defmodule Waffle.Storage.Local do |> URI.encode() end + @impl true def delete(definition, version, file_and_scope) do Path.join([ definition.storage_dir_prefix(), diff --git a/lib/waffle/storage/s3.ex b/lib/waffle/storage/s3.ex index c84ab9a..8d02ee2 100644 --- a/lib/waffle/storage/s3.ex +++ b/lib/waffle/storage/s3.ex @@ -130,6 +130,8 @@ defmodule Waffle.Storage.S3 do """ require Logger + @behaviour Waffle.StorageBehavior + alias ExAws.Config alias ExAws.Request.Url alias ExAws.S3 @@ -138,6 +140,7 @@ defmodule Waffle.Storage.S3 do @default_expiry_time 60 * 5 + @impl true def put(definition, version, {file, scope}) do destination_dir = definition.storage_dir(version, {file, scope}) s3_bucket = s3_bucket(definition, {file, scope}) @@ -152,6 +155,7 @@ defmodule Waffle.Storage.S3 do do_put(file, {s3_bucket, s3_key, s3_options}) end + @impl true def url(definition, version, file_and_scope, options \\ []) do case Keyword.get(options, :signed, false) do false -> build_url(definition, version, file_and_scope, options) @@ -159,6 +163,7 @@ defmodule Waffle.Storage.S3 do end end + @impl true def delete(definition, version, {file, scope}) do s3_bucket(definition, {file, scope}) |> S3.delete_object(s3_key(definition, version, {file, scope}))