spectra_codec behaviour (spectra v0.11.1)
View SourceSummary
Callbacks
Behaviour for custom codecs that extend spectra's encoding, decoding, and schema generation for specific types and formats.
Functions
Decodes Data via a registered codec for the module owning TypeInfo, or returns continue.
Encodes Data via a registered codec for the module owning TypeInfo, or returns continue.
Returns the schema for the module owning TypeInfo via a registered codec, or continue.
Callbacks
-callback decode(Format :: atom(), Module :: module(), TypeRef :: spectra:sp_type_reference(), Input :: dynamic(), SpType :: spectra:sp_type(), Params :: term(), Config :: spectra:sp_config()) -> spectra:codec_decode_result().
-callback encode(Format :: atom(), Module :: module(), TypeRef :: spectra:sp_type_reference(), Data :: dynamic(), SpType :: spectra:sp_type(), Params :: term(), Config :: spectra:sp_config()) -> spectra:codec_encode_result().
Behaviour for custom codecs that extend spectra's encoding, decoding, and schema generation for specific types and formats.
Registering a codec
Codecs are registered in the application environment before use:
application:set_env(spectra, codecs, #{
{my_module, {type, my_type, 0}} => my_codec
}).Alternatively, add -behaviour(spectra_codec) to the module that defines
the type and spectra will discover the codec automatically at load time.
Callback arguments: SpType and Params
Every callback receives two arguments for inspecting the type in context.
Params :: term() — static per-type configuration
Params is the value from the -spectra(#{type_parameters => ...}) attribute
on the type definition, or undefined when no such attribute is present.
-spectra(#{type_parameters => <<"user:">>}).
-type user_id() :: binary().The codec receives <<"user:">> as Params and can use it directly:
encode(json, _Mod, _TypeRef, Data, _SpType, Prefix, _Config) when is_binary(Prefix) ->
{ok, <<Prefix/binary, Data/binary>>};
encode(_Format, _Mod, _TypeRef, _Data, _SpType, _Params, _Config) ->
continue.SpType :: spectra:sp_type() — instantiation node with type-variable bindings
SpType is the type node from the traversal at the point where the codec was
invoked. For generic types this is the reference node — #sp_user_type_ref{}
or #sp_remote_type{} — and it carries the concrete type-variable bindings
of that specific instantiation. Use spectra_type:type_args/1 to extract them.
For a type written as dict:dict(binary(), integer()) the codec receives the
#sp_remote_type{} node and can extract [BinaryType, IntegerType] to
recursively encode/decode keys and values:
encode(json, Mod, _TypeRef, Data, SpType, _Params, Config) ->
TypeInfo = spectra_module_types:get(Mod, Config),
[KeyType, ValueType] = spectra_type:type_args(SpType),
encode_pairs(TypeInfo, KeyType, ValueType, dict:to_list(Data), #{}, Config).Note: when a codec is invoked from the spectra:encode/decode/schema entry
points (rather than via mid-traversal dispatch), SpType is the resolved type
definition and spectra_type:type_args/1 returns []. In practice this only
affects codecs for generic types — they are naturally called from the traversal
where the reference node is available.
-callback schema(Format :: atom(), Module :: module(), TypeRef :: spectra:sp_type_reference(), SpType :: spectra:sp_type(), Params :: term(), Config :: spectra:sp_config()) -> dynamic().
Functions
-spec try_codec_decode(TypeInfo :: spectra:type_info(), Format :: atom(), TypeRef :: spectra:sp_type_reference(), Type :: spectra:sp_type(), Data :: dynamic(), SpType :: spectra:sp_type(), Config :: spectra:sp_config()) -> spectra:codec_decode_result().
Decodes Data via a registered codec for the module owning TypeInfo, or returns continue.
-spec try_codec_encode(TypeInfo :: spectra:type_info(), Format :: atom(), TypeRef :: spectra:sp_type_reference(), Type :: spectra:sp_type(), Data :: dynamic(), SpType :: spectra:sp_type(), Config :: spectra:sp_config()) -> spectra:codec_encode_result().
Encodes Data via a registered codec for the module owning TypeInfo, or returns continue.
-spec try_codec_schema(TypeInfo :: spectra:type_info(), Format :: atom(), TypeRef :: spectra:sp_type_reference(), Type :: spectra:sp_type(), SpType :: spectra:sp_type(), Config :: spectra:sp_config()) -> dynamic() | continue.
Returns the schema for the module owning TypeInfo via a registered codec, or continue.