resx v0.1.3 Resx.Resource
The resource representation.
Link to this section Summary
Functions
Check if two resources or resource references point to the same resource
Retrieve the attribute for a resource or resource reference
Retrieve the attribute keys for a resource or resource reference
Retrieve the attributes for a resource or resource reference
Compare two resources
Discard the resource
Check whether a resource or resource reference exists
Finalise all pending operations on the resource
Finalise all pending operations on the resource
Compute a hash of the resource content using the default hashing function
Compute a hash of the resource content
Check what kind of reference this resource or resource reference is
Retrieve the newest of the two alike resources
Retrieve the oldest of the two alike resources
Open a resource from a pre-existing resource or a resource reference
Open a resource from a pre-existing resource or a resource reference
Get the source of the current resource or resource reference
Store the resource
Store the resource
Stream a resource from a pre-existing resource or a resource reference
Stream a resource from a pre-existing resource or a resource reference
Transform the resource
Transform the resource
Retrieve the URI for a resource or resource reference
Link to this section Types
compare_options() :: [ order: compare_order(), unsure: compare_result(), content: boolean() ]
content() :: Resx.Resource.Content.t() | Resx.Resource.Content.Stream.t()
hasher() ::
{Resx.Resource.Reference.Integrity.algo(),
Callback.callback(binary(), any())}
streamable_hasher() ::
{Resx.Resource.Reference.Integrity.algo(),
initializer ::
Callback.callback(Resx.Resource.Reference.Integrity.algo(), hash_state()),
updater :: Callback.callback(hash_state(), binary(), hash_state()),
finaliser :: Callback.callback(hash_state(), any())}
t(content) :: %Resx.Resource{
content: content,
meta: keyword(),
reference: Resx.Resource.Reference.t()
}
Link to this section Functions
Check if two resources or resource references point to the same resource.
attribute(t() | Resx.ref(), attribute_key()) :: {:ok, any()} | Resx.error(Resx.resource_error() | Resx.reference_error() | :unknown_key)
Retrieve the attribute for a resource or resource reference.
attribute_keys(t() | Resx.ref()) :: {:ok, [attribute_key()]} | Resx.error(Resx.resource_error() | Resx.reference_error())
Retrieve the attribute keys for a resource or resource reference.
attributes(t() | Resx.ref()) :: {:ok, %{optional(attribute_key()) => any()}} | Resx.error(Resx.resource_error() | Resx.reference_error())
Retrieve the attributes for a resource or resource reference.
compare(t(), t(), compare_options()) :: compare_result()
Compare two resources.
The result of the comparison will be one of the following:
nil- The two resources are not alike. And therefore not equal.:eq- The two resources are equal. This will either be integrity equality or if the:contentoption is set totruethen the content's must also be equal.:ltor:gt- The first resource is older or newer than the second. This is based on the integrity timestamps in the order specified in the:orderoption. A:firstorder will iterate through the sources from the original to the current, while:lastorder will iterate from current to original. The first one with a differing timestamp will be used. Note that this does not tell you the equality of the two resources (to do that checkResx.Resource.Reference.Integrity.compare/2or manually compare).:ne- The two resources are not equal. They have equal timestamps for all sources, but one of the sources does not have an equal checksum or if the:contentoption was set totrue, then also if the content's are not equal.:na- The two resources cannot be determined. The timestamps are all equal for all sources, but there were no checksums to compare against for the final iteration (see:order). If the:contentoption is set to true, then the final result will be determined by the content comparison, because of this:nawill no longer be a possible result (it will instead be either:eqor:ne). The:unsureoption can be to change the result term, e.g. if uncertain comparisons should just be considered not equal, then[unsure: :ne]could be passed as an option.
The following options may be passed to this function:
:order- The source order in which the comparisons should occur. An order of:firstwill iterate from the original source to the current, while:lastwill iterate from the current source to the original. By default this is:first.:unsure- Override the result returned when the comparison result is ambiguous. By default this is set to:na.:content- Expects a boolean indicating whether the content data should be compared as well or not. By default this is set tofalse.
discard(t() | Resx.ref(), keyword()) :: :ok | Resx.error(Resx.resource_error() | Resx.reference_error())
Discard the resource.
Only resources or resource references that implement the Resx.Storer behaviour should be passed to this.
exists?(t() | Resx.ref()) :: {:ok, boolean()} | Resx.error(Resx.reference_error())
Check whether a resource or resource reference exists.
finalise!(t() | Resx.ref(), content: boolean(), hash: boolean() | Resx.Resource.Reference.Integrity.algo() | hasher() | streamable_hasher() ) :: t() | no_return()
Finalise all pending operations on the resource.
For more details see Resx.Resource.finalise/2.
Raises any error exceptions.
finalise(t() | Resx.ref(), content: boolean(), hash: boolean() | Resx.Resource.Reference.Integrity.algo() | hasher() | streamable_hasher() ) :: {:ok, t()} | Resx.error(Resx.resource_error() | Resx.reference_error())
Finalise all pending operations on the resource.
The result is a resource with the requested operations applied to it.
Set the :content option to indicate whether content should be included in the final resource (e.g. if it is a stream, its result should be stored instead). By default it is.
Set the :hash option to indicate whether the content hash should be included in the final resource, and which hashing algorithm should be used. By default it is included and is the same as calling Resx.Resource.hash/1.
hash(t() | content()) :: Resx.Resource.Reference.Integrity.checksum()
Compute a hash of the resource content using the default hashing function.
The default hashing function can be configured by giving a :hash option in your config.
config :resx,
hash: { :crc32, { :erlang, :crc32, 1 } } See hash/2 for more information.
hash( t() | content(), Resx.Resource.Reference.Integrity.algo() | hasher() | streamable_hasher() ) :: Resx.Resource.Reference.Integrity.checksum()
Compute a hash of the resource content.
Meta information and resource references are not included in the hash.
Hashing algorithms can take the form of either an atom that is a valid option to :crypto.hash/2, or a tuple of type hasher or streamable_hasher to provide a custom hashing function. Valid function formats are any callback variant, see Callback for more information.
Note: If the resource content is streamable and a hasher is provided for the algo, then the entire content will be decomposed first. If the algo is a streamable_hasher then no decomposition will take place.
The inputs to the initialiser function of a streamable_hasher are optional. The rest are all required.
If the requested hash is the same as the checksum found in the resource, then that checksum will be returned without rehashing the resource content.
iex> Resx.Resource.hash(%Resx.Resource.Content{ type: ["text/plain"], data: "Hello" }, { :crc32, { :erlang, :crc32, 1 } })
{ :crc32, 4157704578 }
iex> Resx.Resource.hash(%Resx.Resource.Content{ type: ["text/plain"], data: "Hello" }, { :crc32, { :erlang, :crc32, [] } })
{ :crc32, 4157704578 }
iex> Resx.Resource.hash(%Resx.Resource.Content{ type: ["text/plain"], data: "Hello" }, { :md5, { :crypto, :hash, [:md5] } })
{ :md5, <<139, 26, 153, 83, 196, 97, 18, 150, 168, 39, 171, 248, 196, 120, 4, 215>> }
iex> Resx.Resource.hash(%Resx.Resource.Content.Stream{ type: ["text/plain"], data: ["He", "l", "lo"] }, { :md5, { :crypto, :hash, [:md5] } })
{ :md5, <<139, 26, 153, 83, 196, 97, 18, 150, 168, 39, 171, 248, 196, 120, 4, 215>> }
iex> Resx.Resource.hash(%Resx.Resource.Content{ type: ["text/plain"], data: "Hello" }, { :md5, { :crypto, :hash_init, 1 }, { :crypto, :hash_update, 2 }, { :crypto, :hash_final, 1 } })
{ :md5, <<139, 26, 153, 83, 196, 97, 18, 150, 168, 39, 171, 248, 196, 120, 4, 215>> }
iex> Resx.Resource.hash(%Resx.Resource.Content.Stream{ type: ["text/plain"], data: ["He", "l", "lo"] }, { :md5, { :crypto, :hash_init, 1 }, { :crypto, :hash_update, 2 }, { :crypto, :hash_final, 1 } })
{ :md5, <<139, 26, 153, 83, 196, 97, 18, 150, 168, 39, 171, 248, 196, 120, 4, 215>> }
iex> Resx.Resource.hash(%Resx.Resource.Content{ type: ["text/plain"], data: "Hello" }, :md5)
{ :md5, <<139, 26, 153, 83, 196, 97, 18, 150, 168, 39, 171, 248, 196, 120, 4, 215>> }
iex> Resx.Resource.hash(%Resx.Resource.Content.Stream{ type: ["text/plain"], data: ["He", "l", "lo"] }, :md5)
{ :md5, <<139, 26, 153, 83, 196, 97, 18, 150, 168, 39, 171, 248, 196, 120, 4, 215>> }
iex> Resx.Resource.hash(%Resx.Resource.Content{ type: ["text/plain"], data: "Hello" }, { :hmac_md5_5, { :crypto, :hmac, [:md5, "secret", 5], 2 } })
{ :hmac_md5_5, <<243, 134, 128, 59, 99>> }
iex> Resx.Resource.hash(%Resx.Resource.Content.Stream{ type: ["text/plain"], data: ["He", "l", "lo"] }, { :hmac_md5_5, { :crypto, :hmac, [:md5, "secret", 5], 2 } })
{ :hmac_md5_5, <<243, 134, 128, 59, 99>> }
iex> Resx.Resource.hash(%Resx.Resource.Content{ type: ["text/plain"], data: "Hello" }, { :hmac_md5_5, { :crypto, :hmac_init, [:md5, "secret"], nil }, { :crypto, :hmac_update, 2 }, { :crypto, :hmac_final_n, [5], 0 } })
{ :hmac_md5_5, <<243, 134, 128, 59, 99>> }
iex> Resx.Resource.hash(%Resx.Resource.Content.Stream{ type: ["text/plain"], data: ["He", "l", "lo"] }, { :hmac_md5_5, { :crypto, :hmac_init, [:md5, "secret"], nil }, { :crypto, :hmac_update, 2 }, { :crypto, :hmac_final_n, [5], 0 } })
{ :hmac_md5_5, <<243, 134, 128, 59, 99>> }
iex> Resx.Resource.hash(%Resx.Resource.Content{ type: ["text/plain"], data: "Hello" }, { :base64, &Base.encode64/1 })
{ :base64, "SGVsbG8=" }
iex> Resx.Resource.hash(%Resx.Resource{ reference: %Resx.Resource.Reference{ integrity: %Resx.Resource.Reference.Integrity{ timestamp: DateTime.utc_now }, adapter: nil, repository: nil }, content: %Resx.Resource.Content{ type: ["text/plain"], data: "Hello" } }, :md5)
{ :md5, <<139, 26, 153, 83, 196, 97, 18, 150, 168, 39, 171, 248, 196, 120, 4, 215>> }
iex> Resx.Resource.hash(%Resx.Resource{ reference: %Resx.Resource.Reference{ integrity: %Resx.Resource.Reference.Integrity{ checksum: { :foo, 1 }, timestamp: DateTime.utc_now }, adapter: nil, repository: nil }, content: %Resx.Resource.Content{ type: ["text/plain"], data: "Hello" } }, :foo)
{ :foo, 1 }
iex> Resx.Resource.hash(%Resx.Resource{ reference: %Resx.Resource.Reference{ integrity: %Resx.Resource.Reference.Integrity{ checksum: { :foo, 1 }, timestamp: DateTime.utc_now }, adapter: nil, repository: nil }, content: %Resx.Resource.Content{ type: ["text/plain"], data: "Hello" } }, :md5)
{ :md5, <<139, 26, 153, 83, 196, 97, 18, 150, 168, 39, 171, 248, 196, 120, 4, 215>> } Check what kind of reference this resource or resource reference is.
iex> Resx.Resource.open!("data:,foo") |> Resx.Resource.kind?(Resx.Producer)
true
iex> Resx.Resource.kind?("data:,foo", Resx.Producer)
true
iex> Resx.Resource.kind?("data:,foo", Resx.Producers.Data)
true
iex> Resx.Resource.kind?("data:,foo", Resx.Storer)
false
iex> Resx.Resource.kind?("data:,foo", Resx.Transformer)
false Retrieve the newest of the two alike resources.
If this cannot be determined, it will return the value in the :default option.
Comparison options can be passed to control how the two resources are compared with each other. For more details on this behaviour see Resx.Resource.compare/3.
iex> old = Resx.Resource.open!("data:,hello")
...> new = Resx.Resource.open!(old)
...> new == Resx.Resource.newest(old, new)
true
iex> old = Resx.Resource.open!("data:,hello")
...> new = Resx.Resource.open!(old)
...> new == Resx.Resource.newest(new, old)
true
iex> old = Resx.Resource.open!("data:,foo")
...> new = Resx.Resource.open!("data:,bar")
...> Resx.Resource.newest(new, old)
nil Retrieve the oldest of the two alike resources.
If this cannot be determined, it will return the value in the :default option.
Comparison options can be passed to control how the two resources are compared with each other. For more details on this behaviour see Resx.Resource.compare/3.
iex> old = Resx.Resource.open!("data:,hello")
...> new = Resx.Resource.open!(old)
...> old == Resx.Resource.oldest(old, new)
true
iex> old = Resx.Resource.open!("data:,hello")
...> new = Resx.Resource.open!(old)
...> old == Resx.Resource.oldest(new, old)
true
iex> old = Resx.Resource.open!("data:,foo")
...> new = Resx.Resource.open!("data:,bar")
...> Resx.Resource.oldest(new, old)
nil Open a resource from a pre-existing resource or a resource reference.
Raises a Resx.Resource.OpenError if the resource could not be opened.
For more details see Resx.Resource.open/2.
open(t() | Resx.ref(), keyword()) :: {:ok, t(Resx.Resource.Content.t())} | Resx.error(Resx.resource_error() | Resx.reference_error())
Open a resource from a pre-existing resource or a resource reference.
source(t() | Resx.ref()) :: {:ok, Resx.ref() | nil} | Resx.error(Resx.reference_error())
Get the source of the current resource or resource reference.
It will return { :ok, nil } if there is no source.
Store the resource.
If a resource reference is given, a stream will be opened to that resource.
Raises a Resx.Storer.StoreError if the resource cannot be saved, or a Resx.Resource.OpenError if the resource could not be opened.
For more details see Resx.Storer.save!/2.
store(t() | Resx.ref(), module(), keyword()) :: {:ok, t()} | Resx.error(Resx.resource_error() | Resx.reference_error())
Store the resource.
If a resource reference is given, a stream will be opened to that resource.
For more details see Resx.Storer.save/2.
Stream a resource from a pre-existing resource or a resource reference.
Raises a Resx.Resource.OpenError if the resource could not be streamed.
For more details see Resx.Resource.stream/2.
stream(t() | Resx.ref(), keyword()) :: {:ok, t(Resx.Resource.Content.Stream.t())} | Resx.error(Resx.resource_error() | Resx.reference_error())
Stream a resource from a pre-existing resource or a resource reference.
Transform the resource.
If a resource reference is given, a stream will be opened to that resource.
Raises a Resx.Transformer.TransformError if the transformation cannot be applied, or a Resx.Resource.OpenError if the resource could not be opened.
For more details see Resx.Transformer.apply!/2.
transform(t() | Resx.ref(), module(), keyword()) :: {:ok, t()} | Resx.error(Resx.resource_error() | Resx.reference_error())
Transform the resource.
If a resource reference is given, a stream will be opened to that resource.
For more details see Resx.Transformer.apply/2.
uri(t() | Resx.Resource.Reference.t()) :: {:ok, Resx.uri()} | Resx.error(Resx.resource_error() | Resx.reference_error())
Retrieve the URI for a resource or resource reference.