defmodule Manganese.AwsKit.Structs.StorageObjectReference do @moduledoc """ """ alias Manganese.CoreKit alias Manganese.AwsKit.Structs @typedoc """ A reference to a stored object in a specific AWS S3 region and bucket. """ @type t :: %Structs.StorageObjectReference{ region: binary, bucket: binary, path: binary } @enforce_keys [ :region, :bucket, :path ] defstruct [ :region, :bucket, :path ] # Deserialization @doc """ """ @spec from_map(map) :: t def from_map(%{ "region" => region, "bucket" => bucket, "path" => path }) do %Structs.StorageObjectReference{ region: region, bucket: bucket, path: path } end # Serialization @doc """ """ @spec to_map(t) :: map def to_map(%Structs.StorageObjectReference{ region: region, bucket: bucket, path: path }) do %{ "region" => region, "bucket" => bucket, "path" => path } end @doc """ """ @spec to_url(t) :: binary def to_url(%Structs.StorageObjectReference{ region: region, bucket: bucket, path: path }) do "https://s3." <> region <> ".amazonaws.com/" <> bucket <> "/" <> path end # Actions @doc """ """ @spec copy(t, t) :: :ok | { :error, CoreKit.Structs.APIError.t } def copy(source_reference, destination_reference) do case ( ExAws.S3.put_object_copy(destination_reference.bucket, destination_reference.path, source_reference.bucket, source_reference.path) |> ExAws.request ) do { :ok, _ } -> :ok { :error, reason } -> { :error, %CoreKit.Structs.APIError{ type: :s3_transfer_failure, status: :service_unavailable }} end end @doc """ """ @spec presigned_link(CoreKit.Enumerations.HttpMethod.t, t, Keyword.t) :: { :ok, CoreKit.Structs.Link.t } | { :error, CoreKit.Structs.APIError.t } def presigned_link(http_method, reference, options) do config = ExAws.Config.new :s3, region: reference.region case ExAws.S3.presigned_url config, http_method, reference.bucket, reference.path, options do { :ok, presigned_url } -> link = CoreKit.Structs.Link.from_uri http_method, presigned_url { :ok, link } { :error, reason } -> { :error, %CoreKit.Structs.APIError{ type: :s3_presigned_url_generation_failure, status: :service_unavailable }} end end # Ecto type use Ecto.Type def type, do: :map def cast(%Structs.StorageObjectReference{} = reference), do: { :ok, reference } def cast(%{} = map), do: { :ok, from_map map } def cast(nil), do: { :ok, nil } def cast(_), do: :error def load(%{} = map), do: { :ok, from_map map } def load(nil), do: { :ok, nil } def load(_), do: :error def dump(%Structs.StorageObjectReference{} = reference), do: { :ok, to_map reference } def dump(nil), do: { :ok, nil } def dump(_), do: :error end