Packmatic.Source.Dynamic (Packmatic v2.0.0)
View SourceRepresents content which may be generated on-demand, for example by another subsystem or via downloading from a signed URL.
For example, a function which dynamically generates a URL (perhaps a signed S3 URL in your own use case) would look like this:
iex(1)> url = "https://example.com"
iex(2)> init_arg = fn -> {:ok, {:url, url}} end
iex(3)> {:ok, {module, source}} = Packmatic.Source.Dynamic.init(init_arg)
iex(4)> module
Packmatic.Source.URL
iex(5)> source.__struct__
Packmatic.Source.URLAnd when used within a Manifest, it would look like this:
iex(1)> url = "https://example.com"
iex(2)> init_arg = fn -> {:ok, {:url, url}} end
iex(3)> entry = [source: {:dynamic, init_arg}, path: "foo.pdf"]
iex(4)> manifest = Packmatic.Manifest.create([entry])
iex(5)> manifest.valid?
trueEven if the function (referenced by the Initialisation Argument) resolves cleanly, the result may still be rejected by the underlying Source, for example if the file does not exist. This kind of error “bubbles up” and is dealt with by the Encoder at runtime.
iex(1)> Packmatic.Source.Dynamic.init(fn -> {:ok, {:file, "example.pdf"}} end)
{:error, :enoent}However, since resolution happens only when the built Stream starts to be consumed, such a Source Entry would be valid when placed in a Manifest ahead of time:
iex(1)> path = "example.pdf"
iex(2)> init_arg = fn -> {:ok, {:file, path}} end
iex(3)> entry = [source: {:dynamic, init_arg}, path: "foo.pdf"]
iex(4)> manifest = Packmatic.Manifest.create([entry])
iex(5)> manifest.valid?
true
Summary
Types
@type init_arg() :: resolve_fun()
@type init_result() :: {:ok, Packmatic.Source.state()} | {:error, term()}
@type resolve_fun() :: (-> resolve_result() | resolve_result_error())
@type resolve_result() :: {:ok, Packmatic.Source.entry()}
@type resolve_result_error() :: {:error, term()}