From dc9c8fca8e4794faa3c1008cc8ee0ed7b5d4708b Mon Sep 17 00:00:00 2001 From: Claudio Ortolina Date: Wed, 17 Sep 2025 09:33:13 +0300 Subject: [PATCH] Add Asset.Transform module Allows building URLs with embedded transformation options --- lib/music_library/assets/transform.ex | 39 ++++++++++++++++++++ test/music_library/assets/transform_test.exs | 5 +++ 2 files changed, 44 insertions(+) create mode 100644 lib/music_library/assets/transform.ex create mode 100644 test/music_library/assets/transform_test.exs diff --git a/lib/music_library/assets/transform.ex b/lib/music_library/assets/transform.ex new file mode 100644 index 00000000..037c56fa --- /dev/null +++ b/lib/music_library/assets/transform.ex @@ -0,0 +1,39 @@ +defmodule MusicLibrary.Assets.Transform do + @derive JSON.Encoder + defstruct [:hash, :width] + + @type t :: %__MODULE__{} + @type payload :: String.t() + + @doc """ + iex> alias MusicLibrary.Assets.Transform + iex> transform = %Transform{hash: "abc123", width: 300} + iex> Transform.encode!(transform) + "eyJoYXNoIjoiYWJjMTIzIiwid2lkdGgiOjMwMH0" + """ + @spec encode!(t()) :: payload() + def encode!(transform) do + transform + |> JSON.encode!() + |> Base.url_encode64(padding: false) + end + + @doc """ + iex> alias MusicLibrary.Assets.Transform + iex> payload = "eyJoYXNoIjoiYWJjMTIzIiwid2lkdGgiOjMwMH0" + iex> Transform.decode!(payload) + %Transform{hash: "abc123", width: 300} + """ + @spec decode!(payload()) :: t() + def decode!(payload) do + params = + payload + |> Base.url_decode64!(padding: false) + |> JSON.decode!() + + struct!(__MODULE__, %{ + hash: params["hash"], + width: params["width"] + }) + end +end diff --git a/test/music_library/assets/transform_test.exs b/test/music_library/assets/transform_test.exs new file mode 100644 index 00000000..8e61be3b --- /dev/null +++ b/test/music_library/assets/transform_test.exs @@ -0,0 +1,5 @@ +defmodule MusicLibrary.Assets.TransformTest do + use ExUnit.Case, async: true + + doctest MusicLibrary.Assets.Transform +end