Skip to content

Commit

Permalink
[#1] exporters documented
Browse files Browse the repository at this point in the history
  • Loading branch information
shizzard committed Mar 6, 2019
1 parent 0f3b792 commit 2a0ffcd
Show file tree
Hide file tree
Showing 10 changed files with 177 additions and 61 deletions.
37 changes: 37 additions & 0 deletions docs/exporters.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Exporters

As opposed of [importers.md](importers.md), exporter functions may be used to pack your data according to your needs.

Exporter function is called right before packing your datastructure back into the `map()`.

You may declare a function `on_export_FIELD_NAME` with the following spec:

```erlang
-spec on_export_FIELD_NAME(InValue :: term()) ->
OutValue :: term() | no_return().
```

You may find a simple example of such a function in [priv_callbacks_on_export.erl](/test/priv/priv_callbacks_on_export.erl):

```erlang
on_export_a(Value) ->
Value * 2.
```

As you may notice, this function doubles the `a` field value before packing it into the map.

You may refer to the modified source code to understand what happens when you declare the exporter:

```erlang
export(#priv_callbacks_on_export{} = Var_record_0) ->
#{a => i_on_export(a, Var_record_0#priv_callbacks_on_export.a)};
export(_) ->
error(badarg).

## ...

i_on_export(a, Var_value_0) ->
on_export_a(Var_value_0);
i_on_export(_, Var_value_0) ->
Var_value_0.
```
4 changes: 1 addition & 3 deletions docs/importers.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ on_import_binary(_) ->
error(badarg).
```

If you will then define a [substructure](substructures.md) for this field, a substructure constructor will be automatically called, and only then the value will be [validated](validators.md).

You may refer to the [`priv_callbacks_on_import.erl`](/test/priv/priv_callbacks_on_import.erl) modified source code to understand what happens when you're declaring the importer:
You may refer to the [`priv_callbacks_on_import.erl`](/test/priv/priv_callbacks_on_import.erl) modified source code to understand what happens when you declare the importer:

```erlang
i_on_import(a, Var_value_0) ->
Expand Down
1 change: 1 addition & 0 deletions include/cloak.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
-define(cloak_generated_function_i_on_import, i_on_import).
-define(cloak_generated_function_i_on_update, i_on_update).
-define(cloak_generated_function_i_on_validate, i_on_validate).
-define(cloak_generated_function_i_on_export, i_on_export).

%% Generated functions arities (for exportable ones)
-define(cloak_generated_function_new_arity, 1).
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
-module(cloak_generate_exporters).
-module(cloak_generate_export).
-behaviour(cloak_generate).
-export([generate/1]).
-include("cloak.hrl").
Expand Down Expand Up @@ -61,21 +61,28 @@ export_clause_body_match_map_field__(Name, _, _, true) ->
%% User-defined callback specified
?es:map_field_assoc(
?es:atom(Name),
?es:application(
?es:atom(?user_definable_export_callback_name(Name)),
[cloak_generate:var__(record, 0)]
)
?es:application(?es:atom(?cloak_generated_function_i_on_export), [
?es:atom(Name),
?es:record_access(
cloak_generate:var__(record, 0),
?es:atom(?get_state()#state.module),
?es:atom(Name)
)
])
);

export_clause_body_match_map_field__(Name, undefined, undefined, false) ->
export_clause_body_match_map_field__(Name, undefined, undefined, _) ->
%% No user-defined callback, no substructures specified
?es:map_field_assoc(
?es:atom(Name),
?es:record_access(
cloak_generate:var__(record, 0),
?es:atom(?get_state()#state.module),
?es:atom(Name)
)
?es:application(?es:atom(?cloak_generated_function_i_on_export), [
?es:atom(Name),
?es:record_access(
cloak_generate:var__(record, 0),
?es:atom(?get_state()#state.module),
?es:atom(Name)
)
])
);

export_clause_body_match_map_field__(Name, UserDefinedSubstructureModule, undefined, _) ->
Expand Down
71 changes: 71 additions & 0 deletions src/cloak_generate/cloak_generate_i_on_export.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
-module(cloak_generate_i_on_export).
-behaviour(cloak_generate).
-export([generate/1]).
-include("cloak.hrl").


%% Generate callback


generate(_Forms) ->
[
i_on_export__(
?get_state()#state.required_record_fields
++ ?get_state()#state.optional_record_fields
)
].


%% Validators (?MODULE:validate/2)


i_on_export__(RecordFields) ->
?es:function(?es:atom(?cloak_generated_function_i_on_export), i_on_export_clauses__(RecordFields)).


i_on_export_clauses__(RecordsFields) ->
i_on_export_clauses__(RecordsFields, []).


i_on_export_clauses__([], Acc) ->
lists:reverse([?es:clause(
i_on_export_clause_patterns_mismatch__(),
_Guards = none,
i_on_export_clause_body_mismatch__()
) | Acc]);

i_on_export_clauses__([#record_field{name = Name} | RecordFields], Acc) ->
MaybeUserDefinedImportCallback = ?user_definable_export_callback_name(Name),
case lists:member(
MaybeUserDefinedImportCallback,
?get_state()#state.user_defined_export_callbacks
) of
true ->
i_on_export_clauses__(RecordFields, [?es:clause(
i_on_export_clause_patterns_match__(Name),
_Guards = none,
i_on_export_clause_body_match__(Name)
) | Acc]);
false ->
i_on_export_clauses__(RecordFields, Acc)
end.


i_on_export_clause_patterns_match__(Name) ->
[
?es:atom(Name),
cloak_generate:var__(value, 0)
].


i_on_export_clause_body_match__(Name) ->
MaybeUserDefinedImportCallback = ?user_definable_export_callback_name(Name),
[?es:application(?es:atom(MaybeUserDefinedImportCallback), [cloak_generate:var__(value, 0)])].


i_on_export_clause_patterns_mismatch__() ->
[?es:underscore(), cloak_generate:var__(value, 0)].


i_on_export_clause_body_mismatch__() ->
[cloak_generate:var__(value, 0)].
34 changes: 17 additions & 17 deletions src/cloak_generate/cloak_generate_i_on_import.erl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

generate(_Forms) ->
[
i_import__(
i_on_import__(
?get_state()#state.required_record_fields
++ ?get_state()#state.optional_record_fields
)
Expand All @@ -19,53 +19,53 @@ generate(_Forms) ->
%% Validators (?MODULE:validate/2)


i_import__(RecordFields) ->
?es:function(?es:atom(?cloak_generated_function_i_on_import), i_import_clauses__(RecordFields)).
i_on_import__(RecordFields) ->
?es:function(?es:atom(?cloak_generated_function_i_on_import), i_on_import_clauses__(RecordFields)).


i_import_clauses__(RecordsFields) ->
i_import_clauses__(RecordsFields, []).
i_on_import_clauses__(RecordsFields) ->
i_on_import_clauses__(RecordsFields, []).


i_import_clauses__([], Acc) ->
i_on_import_clauses__([], Acc) ->
lists:reverse([?es:clause(
i_import_clause_patterns_mismatch__(),
i_on_import_clause_patterns_mismatch__(),
_Guards = none,
i_import_clause_body_mismatch__()
i_on_import_clause_body_mismatch__()
) | Acc]);

i_import_clauses__([#record_field{name = Name} | RecordFields], Acc) ->
i_on_import_clauses__([#record_field{name = Name} | RecordFields], Acc) ->
MaybeUserDefinedImportCallback = ?user_definable_import_callback_name(Name),
case lists:member(
MaybeUserDefinedImportCallback,
?get_state()#state.user_defined_import_callbacks
) of
true ->
i_import_clauses__(RecordFields, [?es:clause(
i_import_clause_patterns_match__(Name),
i_on_import_clauses__(RecordFields, [?es:clause(
i_on_import_clause_patterns_match__(Name),
_Guards = none,
i_import_clause_body_match__(Name)
i_on_import_clause_body_match__(Name)
) | Acc]);
false ->
i_import_clauses__(RecordFields, Acc)
i_on_import_clauses__(RecordFields, Acc)
end.


i_import_clause_patterns_match__(Name) ->
i_on_import_clause_patterns_match__(Name) ->
[
?es:atom(Name),
cloak_generate:var__(value, 0)
].


i_import_clause_body_match__(Name) ->
i_on_import_clause_body_match__(Name) ->
MaybeUserDefinedImportCallback = ?user_definable_import_callback_name(Name),
[?es:application(?es:atom(MaybeUserDefinedImportCallback), [cloak_generate:var__(value, 0)])].


i_import_clause_patterns_mismatch__() ->
i_on_import_clause_patterns_mismatch__() ->
[?es:underscore(), cloak_generate:var__(value, 0)].


i_import_clause_body_mismatch__() ->
i_on_import_clause_body_mismatch__() ->
[cloak_generate:var__(value, 0)].
20 changes: 10 additions & 10 deletions src/cloak_generate/cloak_generate_i_on_update.erl
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,24 @@


generate(_Forms) ->
[i_update__()].
[i_on_update__()].


%% Update


i_update__() ->
[?es:function(?es:atom(?cloak_generated_function_i_on_update), i_update_clauses__())].
i_on_update__() ->
[?es:function(?es:atom(?cloak_generated_function_i_on_update), i_on_update_clauses__())].


i_update_clauses__() ->
i_on_update_clauses__() ->
[
?es:clause(i_update_clause_patterns_match__(), _Guards = none, i_update_clause_body_match__()),
?es:clause(i_update_clause_patterns_mismatch__(), _Guards = none, i_update_clause_body_mismatch__())
?es:clause(i_on_update_clause_patterns_match__(), _Guards = none, i_on_update_clause_body_match__()),
?es:clause(i_on_update_clause_patterns_mismatch__(), _Guards = none, i_on_update_clause_body_mismatch__())
].


i_update_clause_patterns_match__() ->
i_on_update_clause_patterns_match__() ->
[
?es:match_expr(
?es:record_expr(?es:atom(?get_state()#state.module), []),
Expand All @@ -34,7 +34,7 @@ i_update_clause_patterns_match__() ->
].


i_update_clause_body_match__() ->
i_on_update_clause_body_match__() ->
case ?get_state()#state.user_definable_on_update_callback_exists of
true ->
[?es:application(
Expand All @@ -46,9 +46,9 @@ i_update_clause_body_match__() ->
end.


i_update_clause_patterns_mismatch__() ->
i_on_update_clause_patterns_mismatch__() ->
[?es:underscore()].


i_update_clause_body_mismatch__() ->
i_on_update_clause_body_mismatch__() ->
[cloak_generate:error_badarg__()].
34 changes: 17 additions & 17 deletions src/cloak_generate/cloak_generate_i_on_validate.erl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

generate(_Forms) ->
[
i_validate__(
i_on_validate__(
?get_state()#state.required_record_fields
++ ?get_state()#state.optional_record_fields
++ ?get_state()#state.protected_record_fields
Expand All @@ -21,54 +21,54 @@ generate(_Forms) ->
%% Validators (?MODULE:validate/2)


i_validate__(RecordFields) ->
?es:function(?es:atom(?cloak_generated_function_i_on_validate), i_validate_clauses__(RecordFields)).
i_on_validate__(RecordFields) ->
?es:function(?es:atom(?cloak_generated_function_i_on_validate), i_on_validate_clauses__(RecordFields)).


i_validate_clauses__(RecordsFields) ->
i_validate_clauses__(RecordsFields, []).
i_on_validate_clauses__(RecordsFields) ->
i_on_validate_clauses__(RecordsFields, []).


i_validate_clauses__([], Acc) ->
i_on_validate_clauses__([], Acc) ->
lists:reverse([?es:clause(
i_validate_clause_patterns_mismatch__(),
i_on_validate_clause_patterns_mismatch__(),
_Guards = none,
i_validate_clause_body_mismatch__()
i_on_validate_clause_body_mismatch__()
) | Acc]);

i_validate_clauses__([#record_field{name = Name} | RecordFields], Acc) ->
i_on_validate_clauses__([#record_field{name = Name} | RecordFields], Acc) ->
MaybeUserDefinedValidatorCallback = ?user_definable_validator_callback_name(Name),
case lists:member(
MaybeUserDefinedValidatorCallback,
?get_state()#state.user_defined_validator_callbacks
) of
true ->
i_validate_clauses__(RecordFields, [?es:clause(
i_validate_clause_patterns_match__(Name),
i_on_validate_clauses__(RecordFields, [?es:clause(
i_on_validate_clause_patterns_match__(Name),
_Guards = none,
i_validate_clause_body_match__(Name)
i_on_validate_clause_body_match__(Name)
) | Acc]);
false ->
i_validate_clauses__(RecordFields, Acc)
i_on_validate_clauses__(RecordFields, Acc)
end.


i_validate_clause_patterns_match__(Name) ->
i_on_validate_clause_patterns_match__(Name) ->
[
?es:atom(Name),
cloak_generate:var__(value, 0)
].


i_validate_clause_body_match__(Name) ->
i_on_validate_clause_body_match__(Name) ->
MaybeUserDefinedValidatorCallback = ?user_definable_validator_callback_name(Name),
[?es:application(?es:atom(MaybeUserDefinedValidatorCallback), [cloak_generate:var__(value, 0)])].



i_validate_clause_patterns_mismatch__() ->
i_on_validate_clause_patterns_mismatch__() ->
[?es:underscore(), cloak_generate:var__(value, 0)].


i_validate_clause_body_mismatch__() ->
i_on_validate_clause_body_mismatch__() ->
[cloak_generate:var__(value, 0)].
Loading

0 comments on commit 2a0ffcd

Please sign in to comment.