Current section
Files
Jump to
Current section
Files
src/glemplate@renderer.erl
-module(glemplate@renderer).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([render/3]).
-export_type([render_error/0, stringify_error/0, render_options/0]).
-type render_error() :: {assign_not_found,
glemplate@ast:var(),
gleam@dict:dict(binary(), glemplate@assigns:assign_data())} |
{assign_not_iterable,
glemplate@ast:var(),
gleam@dict:dict(binary(), glemplate@assigns:assign_data())} |
{assign_not_stringifiable,
glemplate@ast:var(),
gleam@dict:dict(binary(), glemplate@assigns:assign_data())} |
{assign_field_not_found,
glemplate@ast:var(),
binary(),
gleam@dict:dict(binary(), glemplate@assigns:assign_data())} |
{assign_not_field_accessible,
glemplate@ast:var(),
gleam@dict:dict(binary(), glemplate@assigns:assign_data())} |
{child_template_not_found, binary()}.
-type stringify_error() :: stringify_error.
-type render_options() :: {render_options,
fun((binary()) -> gleam@string_tree:string_tree()),
gleam@dict:dict(binary(), glemplate@ast:template())}.
-file("/Users/nicd/svn/glemplate/src/glemplate/renderer.gleam", 233).
-spec access_field(
glemplate@assigns:assign_data(),
binary(),
glemplate@ast:var(),
gleam@dict:dict(binary(), glemplate@assigns:assign_data())
) -> {ok, glemplate@assigns:assign_data()} | {error, render_error()}.
access_field(Container, Field, Accessor, Assigns) ->
case Container of
{dict, D} ->
case gleam_stdlib:map_get(D, Field) of
{ok, Data} ->
{ok, Data};
{error, _} ->
{error, {assign_field_not_found, Accessor, Field, Assigns}}
end;
_ ->
{error, {assign_not_field_accessible, Accessor, Assigns}}
end.
-file("/Users/nicd/svn/glemplate/src/glemplate/renderer.gleam", 256).
-spec stringify(glemplate@assigns:assign_data()) -> {ok, binary()} |
{error, stringify_error()}.
stringify(Data) ->
case Data of
{string, S} ->
{ok, S};
{int, I} ->
{ok, erlang:integer_to_binary(I)};
_ ->
{error, stringify_error}
end.
-file("/Users/nicd/svn/glemplate/src/glemplate/renderer.gleam", 126).
-spec render_output(
glemplate@assigns:assign_data(),
boolean(),
glemplate@ast:var(),
gleam@dict:dict(binary(), glemplate@assigns:assign_data()),
gleam@string_tree:string_tree(),
render_options()
) -> {ok, gleam@string_tree:string_tree()} | {error, render_error()}.
render_output(Data, Raw, Var, Assigns, Acc, Options) ->
Str_result = stringify(Data),
case Str_result of
{ok, Str} ->
Out = case Raw of
true ->
gleam@string_tree:append(Acc, Str);
false ->
gleam_stdlib:iodata_append(
Acc,
(erlang:element(2, Options))(Str)
)
end,
{ok, Out};
{error, _} ->
{error, {assign_not_stringifiable, Var, Assigns}}
end.
-file("/Users/nicd/svn/glemplate/src/glemplate/renderer.gleam", 264).
-spec resolve_lazy(glemplate@assigns:assign_data()) -> glemplate@assigns:assign_data().
resolve_lazy(Data) ->
case Data of
{lazy, Lazy_fn} ->
resolve_lazy(Lazy_fn());
Other ->
Other
end.
-file("/Users/nicd/svn/glemplate/src/glemplate/renderer.gleam", 213).
-spec get_assign(
gleam@dict:dict(binary(), glemplate@assigns:assign_data()),
glemplate@ast:var()
) -> {ok, glemplate@assigns:assign_data()} | {error, render_error()}.
get_assign(Assigns, Var) ->
gleam@result:then(case Var of
{assign, Name} ->
Get_result = gleam_stdlib:map_get(Assigns, Name),
case Get_result of
{ok, Data} ->
{ok, Data};
{error, _} ->
{error, {assign_not_found, Var, Assigns}}
end;
{field_access, Container, Field} ->
gleam@result:then(
get_assign(Assigns, Container),
fun(Data@1) -> access_field(Data@1, Field, Var, Assigns) end
)
end, fun(Data@2) -> {ok, resolve_lazy(Data@2)} end).
-file("/Users/nicd/svn/glemplate/src/glemplate/renderer.gleam", 81).
-spec render_node(
glemplate@ast:node_(),
gleam@dict:dict(binary(), glemplate@assigns:assign_data()),
gleam@string_tree:string_tree(),
render_options()
) -> {ok, gleam@string_tree:string_tree()} | {error, render_error()}.
render_node(Node, Assigns, Acc, Options) ->
case Node of
{text, Str} ->
{ok, gleam@string_tree:append(Acc, Str)};
{dynamic, Dynamic} ->
render_dynamic(Dynamic, Assigns, Acc, Options);
{nodes, Nodes} ->
render_nodes(Nodes, Assigns, Acc, Options)
end.
-file("/Users/nicd/svn/glemplate/src/glemplate/renderer.gleam", 70).
-spec render_nodes(
list(glemplate@ast:node_()),
gleam@dict:dict(binary(), glemplate@assigns:assign_data()),
gleam@string_tree:string_tree(),
render_options()
) -> {ok, gleam@string_tree:string_tree()} | {error, render_error()}.
render_nodes(Nodes, Assigns, Acc, Options) ->
gleam@list:try_fold(
Nodes,
Acc,
fun(Acc@1, Node) -> render_node(Node, Assigns, Acc@1, Options) end
).
-file("/Users/nicd/svn/glemplate/src/glemplate/renderer.gleam", 62).
-spec render(
glemplate@ast:template(),
gleam@dict:dict(binary(), glemplate@assigns:assign_data()),
render_options()
) -> {ok, gleam@string_tree:string_tree()} | {error, render_error()}.
render(Template, Assigns, Opts) ->
render_nodes(
erlang:element(3, Template),
Assigns,
gleam@string_tree:new(),
Opts
).
-file("/Users/nicd/svn/glemplate/src/glemplate/renderer.gleam", 149).
-spec render_if(
glemplate@assigns:assign_data(),
list(glemplate@ast:node_()),
list(glemplate@ast:node_()),
gleam@dict:dict(binary(), glemplate@assigns:assign_data()),
gleam@string_tree:string_tree(),
render_options()
) -> {ok, gleam@string_tree:string_tree()} | {error, render_error()}.
render_if(Data, If_true, If_false, Assigns, Acc, Options) ->
Nodes = case Data of
{bool, false} ->
If_false;
{string, <<""/utf8>>} ->
If_false;
{int, 0} ->
If_false;
{list, []} ->
If_false;
{dict, D} ->
case not gleam@dict:is_empty(D) of
true ->
If_true;
false ->
If_false
end;
_ ->
If_true
end,
render_nodes(Nodes, Assigns, Acc, Options).
-file("/Users/nicd/svn/glemplate/src/glemplate/renderer.gleam", 170).
-spec render_iter(
glemplate@assigns:assign_data(),
glemplate@ast:var(),
binary(),
list(glemplate@ast:node_()),
gleam@dict:dict(binary(), glemplate@assigns:assign_data()),
gleam@string_tree:string_tree(),
render_options()
) -> {ok, gleam@string_tree:string_tree()} | {error, render_error()}.
render_iter(Data, Over, Binding, Nodes, Assigns, Acc, Options) ->
case Data of
{list, Items} ->
gleam@list:try_fold(
Items,
Acc,
fun(Output, Item) ->
New_assigns = gleam@dict:insert(Assigns, Binding, Item),
render_nodes(Nodes, New_assigns, Output, Options)
end
);
_ ->
{error, {assign_not_iterable, Over, Assigns}}
end.
-file("/Users/nicd/svn/glemplate/src/glemplate/renderer.gleam", 190).
-spec render_child(
binary(),
gleam@dict:dict(binary(), glemplate@assigns:assign_data()),
list({glemplate@ast:var(), binary()}),
gleam@string_tree:string_tree(),
render_options()
) -> {ok, gleam@string_tree:string_tree()} | {error, render_error()}.
render_child(Template_name, Assigns, Assigns_map, Acc, Options) ->
gleam@result:then(
begin
_pipe = gleam_stdlib:map_get(
erlang:element(3, Options),
Template_name
),
gleam@result:replace_error(
_pipe,
{child_template_not_found, Template_name}
)
end,
fun(Template) ->
gleam@result:then(
gleam@list:try_fold(
Assigns_map,
maps:new(),
fun(Acc@1, Mapping) ->
{From, To} = Mapping,
gleam@result:then(
get_assign(Assigns, From),
fun(Assign) ->
{ok, gleam@dict:insert(Acc@1, To, Assign)}
end
)
end
),
fun(New_assigns) ->
render_nodes(
erlang:element(3, Template),
New_assigns,
Acc,
Options
)
end
)
end
).
-file("/Users/nicd/svn/glemplate/src/glemplate/renderer.gleam", 94).
-spec render_dynamic(
glemplate@ast:dynamic_node(),
gleam@dict:dict(binary(), glemplate@assigns:assign_data()),
gleam@string_tree:string_tree(),
render_options()
) -> {ok, gleam@string_tree:string_tree()} | {error, render_error()}.
render_dynamic(Node, Assigns, Acc, Options) ->
case Node of
{output, Var} ->
_pipe = get_assign(Assigns, Var),
gleam@result:then(
_pipe,
fun(Data) ->
render_output(Data, false, Var, Assigns, Acc, Options)
end
);
{raw_output, Var@1} ->
_pipe@1 = get_assign(Assigns, Var@1),
gleam@result:then(
_pipe@1,
fun(Data@1) ->
render_output(Data@1, true, Var@1, Assigns, Acc, Options)
end
);
{'if', Var@2, If_true, If_false} ->
_pipe@2 = get_assign(Assigns, Var@2),
gleam@result:then(
_pipe@2,
fun(Data@2) ->
render_if(Data@2, If_true, If_false, Assigns, Acc, Options)
end
);
{iter, Over, Binding, Nodes} ->
_pipe@3 = get_assign(Assigns, Over),
gleam@result:then(
_pipe@3,
fun(Data@3) ->
render_iter(
Data@3,
Over,
Binding,
Nodes,
Assigns,
Acc,
Options
)
end
);
{render, Tpl, Assigns_map} ->
render_child(Tpl, Assigns, Assigns_map, Acc, Options)
end.