defmodule NLdoc.Spec.Asset do @moduledoc """ This module defines the Ecto schema for the NLdoc spec Asset object. """ use NLdoc.Spec.Schema, type: "https://spec.nldoc.nl/Resource/Asset" typed_embedded_schema null: false do field :id, Ecto.UUID field :type, :string, default: @resource_type field :data, :string field :content_type, :string field :encoding, Ecto.Enum, values: [:base64] field(:descriptors, {:array, PolymorphicEmbed}, types: map(NLdoc.Spec.descriptors()), type_field_name: :type, on_replace: :delete, default: [], array?: true ) :: [NLdoc.Spec.descriptor()] end def changeset(object, attrs) do object |> cast(attrs, [:id, :type, :data, :content_type, :encoding], @cast_opts) |> cast_polymorphic_embed(:descriptors, @cast_opts) |> validate_required([:id, :type, :data, :content_type]) end @doc """ Converts base64 to Asset resource. ## Examples iex> NLdoc.Spec.Asset.from_base64("123", "data:image/gif;base64,R0lGODlhAQABAAAAACw=") %NLdoc.Spec.Asset{ id: "123", encoding: :base64, content_type: "image/gif", data: "R0lGODlhAQABAAAAACw=" } """ @spec from_base64(id :: String.t(), String.t()) :: NLdoc.Spec.Asset.t() def from_base64(id, "data:" <> rest) do [content_type, data] = rest |> String.split(";base64,", parts: 2) %__MODULE__{id: id, encoding: :base64, content_type: content_type, data: data} end @doc """ Converts Asset resource to base64. ## Examples iex> NLdoc.Spec.Asset.to_base64(%NLdoc.Spec.Asset{ ...> id: "123", ...> encoding: :base64, ...> content_type: "image/gif", ...> data: "R0lGODlhAQABAAAAACw=" ...> }) "data:image/gif;base64,R0lGODlhAQABAAAAACw=" iex> NLdoc.Spec.Asset.to_base64(%NLdoc.Spec.Asset{ ...> id: "123", ...> content_type: "image/gif", ...> encoding: nil, ...> data: <<71, 73, 70, 56, 57, 97, 1, 0, 1, 0, 0, 0, 0, 44>> ...> }) "data:image/gif;base64,R0lGODlhAQABAAAAACw=" """ @spec to_base64(asset :: NLdoc.Spec.Asset.t()) :: String.t() def to_base64(%__MODULE__{encoding: :base64, content_type: content_type, data: data}) do "data:#{content_type};base64,#{data}" end def to_base64(%__MODULE__{encoding: nil, content_type: content_type, data: data}) do "data:#{content_type};base64," <> Base.encode64(data) end end