Packages

A markup language to define ER schemas

Current section

Files

Jump to
prequel src prequel@pretty_printer.erl
Raw

src/prequel@pretty_printer.erl

-module(prequel@pretty_printer).
-compile([no_auto_import, nowarn_unused_vars]).
-export([format/1]).
-spec entity_has_empty_body(prequel@ast:entity()) -> boolean().
entity_has_empty_body(Entity) ->
{entity, _, _, Keys, Attributes, Inner_relationships, Children} = Entity,
case {Keys, Attributes, Inner_relationships, Children} of
{[], [], [], none} ->
true;
{_, _, _, _} ->
false
end.
-spec pretty_cardinality(prequel@ast:cardinality()) -> gleam@string_builder:string_builder().
pretty_cardinality(Cardinality) ->
case Cardinality of
{bounded, _, Min, Max} ->
gleam@string_builder:from_strings(
[<<"("/utf8>>,
gleam@int:to_string(Min),
<<"-"/utf8>>,
gleam@int:to_string(Max),
<<")"/utf8>>]
);
{unbounded, _, Min@1} ->
gleam@string_builder:from_strings(
[<<"("/utf8>>, gleam@int:to_string(Min@1), <<"-N)"/utf8>>]
)
end.
-spec indent(gleam@string_builder:string_builder(), integer()) -> gleam@string_builder:string_builder().
indent(Builder, Indentation) ->
Spaces = gleam@string_builder:from_strings(
gleam@list:repeat(<<" "/utf8>>, Indentation)
),
gleam@string_builder:append_builder(Spaces, Builder).
-spec indent_string(binary(), integer()) -> gleam@string_builder:string_builder().
indent_string(String, Indentation) ->
indent(gleam@string_builder:from_string(String), Indentation).
-spec pretty_key(prequel@ast:key(), integer()) -> gleam@string_builder:string_builder().
pretty_key(Key, Indentation) ->
case Key of
{single_key, _, Key@1, _} ->
_pipe = indent_string(<<"-* "/utf8>>, Indentation),
gleam@string_builder:append(_pipe, Key@1);
{composed_key, _, Keys} ->
_pipe@1 = Keys,
_pipe@2 = non_empty_list:to_list(_pipe@1),
_pipe@3 = gleam@list:intersperse(_pipe@2, <<" & "/utf8>>),
_pipe@4 = gleam@string_builder:from_strings(_pipe@3),
gleam@string_builder:prepend_builder(
_pipe@4,
indent_string(<<"-* "/utf8>>, Indentation)
)
end.
-spec pretty_attribute(prequel@ast:attribute(), integer()) -> gleam@string_builder:string_builder().
pretty_attribute(Attribute, Indentation) ->
Lollipop = indent_string(<<"-o "/utf8>>, Indentation),
case erlang:element(4, Attribute) of
{bounded, _, 1, 1} ->
gleam@string_builder:append(Lollipop, erlang:element(3, Attribute));
_ ->
_pipe = Lollipop,
_pipe@1 = gleam@string_builder:append(
_pipe,
erlang:element(3, Attribute)
),
_pipe@2 = gleam@string_builder:append(_pipe@1, <<" : "/utf8>>),
gleam@string_builder:append_builder(
_pipe@2,
pretty_cardinality(erlang:element(4, Attribute))
)
end.
-spec pretty_inner_relationship(prequel@ast:relationship(), binary(), integer()) -> gleam@string_builder:string_builder().
pretty_inner_relationship(Inner_relationship, Entity_name, Indentation) ->
_assert_subject = begin
_pipe = erlang:element(5, Inner_relationship),
_pipe@1 = non_empty_list:prepend(
_pipe,
erlang:element(4, Inner_relationship)
),
_pipe@2 = non_empty_list:to_list(_pipe@1),
gleam@list:partition(
_pipe@2,
fun(Entity) -> erlang:element(3, Entity) =:= Entity_name end
)
end,
{[Outer_entity], [Inner_entity]} = case _assert_subject of
{[_], [_]} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"prequel/pretty_printer"/utf8>>,
function => <<"pretty_inner_relationship"/utf8>>,
line => 107})
end,
Inner_relationship_head = begin
_pipe@3 = indent_string(<<"-> "/utf8>>, Indentation),
_pipe@4 = gleam@string_builder:append(
_pipe@3,
erlang:element(3, Inner_relationship)
),
_pipe@5 = gleam@string_builder:append(_pipe@4, <<" : "/utf8>>),
_pipe@6 = gleam@string_builder:append_builder(
_pipe@5,
pretty_cardinality(erlang:element(4, Outer_entity))
),
_pipe@7 = gleam@string_builder:append(_pipe@6, <<" "/utf8>>),
_pipe@8 = gleam@string_builder:append(
_pipe@7,
erlang:element(3, Inner_entity)
),
_pipe@9 = gleam@string_builder:append(_pipe@8, <<" "/utf8>>),
gleam@string_builder:append_builder(
_pipe@9,
pretty_cardinality(erlang:element(4, Inner_entity))
)
end,
case erlang:element(6, Inner_relationship) of
[] ->
Inner_relationship_head;
_ ->
_pipe@10 = Inner_relationship_head,
_pipe@11 = gleam@string_builder:append(_pipe@10, <<" {\n"/utf8>>),
_pipe@15 = gleam@string_builder:append_builder(
_pipe@11,
begin
_pipe@12 = erlang:element(6, Inner_relationship),
_pipe@13 = gleam@list:map(
_pipe@12,
fun(_capture) ->
pretty_attribute(_capture, Indentation + 2)
end
),
_pipe@14 = gleam@string_builder:join(
_pipe@13,
<<"\n"/utf8>>
),
gleam@string_builder:append(_pipe@14, <<"\n"/utf8>>)
end
),
gleam@string_builder:append_builder(
_pipe@15,
indent_string(<<"}"/utf8>>, Indentation)
)
end.
-spec pretty_relationship_entity(prequel@ast:relationship_entity()) -> gleam@string_builder:string_builder().
pretty_relationship_entity(Entity) ->
_pipe = [<<"-> "/utf8>>, erlang:element(3, Entity), <<" : "/utf8>>],
_pipe@1 = gleam@string_builder:from_strings(_pipe),
gleam@string_builder:append_builder(
_pipe@1,
pretty_cardinality(erlang:element(4, Entity))
).
-spec pretty_relationship_body(prequel@ast:relationship()) -> gleam@string_builder:string_builder().
pretty_relationship_body(Relationship) ->
Entities = begin
_pipe = erlang:element(5, Relationship),
_pipe@1 = non_empty_list:prepend(_pipe, erlang:element(4, Relationship)),
_pipe@2 = non_empty_list:to_list(_pipe@1),
_pipe@3 = gleam@list:map(_pipe@2, fun pretty_relationship_entity/1),
_pipe@4 = gleam@list:map(
_pipe@3,
fun(_capture) -> indent(_capture, 2) end
),
gleam@string_builder:join(_pipe@4, <<"\n"/utf8>>)
end,
Attributes = begin
_pipe@5 = erlang:element(6, Relationship),
_pipe@6 = gleam@list:map(
_pipe@5,
fun(_capture@1) -> pretty_attribute(_capture@1, 2) end
),
gleam@string_builder:join(_pipe@6, <<"\n"/utf8>>)
end,
_pipe@7 = [Entities, Attributes],
_pipe@8 = gleam@list:filter(
_pipe@7,
fun(Builder) -> not gleam@string_builder:is_empty(Builder) end
),
_pipe@9 = gleam@string_builder:join(_pipe@8, <<"\n\n"/utf8>>),
gleam@string_builder:append(_pipe@9, <<"\n"/utf8>>).
-spec pretty_relationship(prequel@ast:relationship()) -> gleam@string_builder:string_builder().
pretty_relationship(Relationship) ->
_pipe = gleam@string_builder:new(),
_pipe@1 = gleam@string_builder:append(_pipe, <<"relationship "/utf8>>),
_pipe@2 = gleam@string_builder:append(
_pipe@1,
erlang:element(3, Relationship)
),
_pipe@3 = gleam@string_builder:append(_pipe@2, <<" {\n"/utf8>>),
_pipe@4 = gleam@string_builder:append_builder(
_pipe@3,
pretty_relationship_body(Relationship)
),
gleam@string_builder:append(_pipe@4, <<"}"/utf8>>).
-spec pretty_hierarchy(prequel@ast:hierarchy(), integer()) -> gleam@string_builder:string_builder().
pretty_hierarchy(Hierarchy, Indentation) ->
Totality = case erlang:element(4, Hierarchy) of
total ->
<<"total"/utf8>>;
partial ->
<<"partial"/utf8>>
end,
Overlapping = case erlang:element(3, Hierarchy) of
overlapped ->
<<"overlapped"/utf8>>;
disjoint ->
<<"disjoint"/utf8>>
end,
Entities = begin
_pipe = erlang:element(5, Hierarchy),
_pipe@1 = non_empty_list:to_list(_pipe),
_pipe@2 = gleam@list:map(
_pipe@1,
fun(_capture) -> pretty_entity(_capture, Indentation + 2) end
),
gleam@string_builder:join(_pipe@2, <<"\n\n"/utf8>>)
end,
_pipe@3 = indent_string(Totality, Indentation),
_pipe@4 = gleam@string_builder:append(_pipe@3, <<" "/utf8>>),
_pipe@5 = gleam@string_builder:append(_pipe@4, Overlapping),
_pipe@6 = gleam@string_builder:append(_pipe@5, <<" hierarchy {\n"/utf8>>),
_pipe@7 = gleam@string_builder:append_builder(_pipe@6, Entities),
_pipe@8 = gleam@string_builder:append(_pipe@7, <<"\n"/utf8>>),
gleam@string_builder:append_builder(
_pipe@8,
indent_string(<<"}"/utf8>>, Indentation)
).
-spec pretty_entity(prequel@ast:entity(), integer()) -> gleam@string_builder:string_builder().
pretty_entity(Entity, Indentation) ->
Entity_head = begin
_pipe = gleam@string_builder:from_strings(
[<<"entity "/utf8>>, erlang:element(3, Entity)]
),
indent(_pipe, Indentation)
end,
gleam@bool:guard(
entity_has_empty_body(Entity),
Entity_head,
fun() -> _pipe@1 = Entity_head,
_pipe@2 = gleam@string_builder:append(_pipe@1, <<" {\n"/utf8>>),
_pipe@3 = gleam@string_builder:append_builder(
_pipe@2,
pretty_entity_body(Entity, Indentation + 2)
),
gleam@string_builder:append_builder(
_pipe@3,
indent_string(<<"}"/utf8>>, Indentation)
) end
).
-spec pretty_entity_body(prequel@ast:entity(), integer()) -> gleam@string_builder:string_builder().
pretty_entity_body(Entity, Indentation) ->
Keys = begin
_pipe = erlang:element(4, Entity),
_pipe@1 = gleam@list:map(
_pipe,
fun(_capture) -> pretty_key(_capture, Indentation) end
),
gleam@string_builder:join(_pipe@1, <<"\n"/utf8>>)
end,
Attributes = begin
_pipe@2 = erlang:element(5, Entity),
_pipe@3 = gleam@list:map(
_pipe@2,
fun(_capture@1) -> pretty_attribute(_capture@1, Indentation) end
),
gleam@string_builder:join(_pipe@3, <<"\n"/utf8>>)
end,
Inner_relationships = begin
_pipe@4 = erlang:element(6, Entity),
_pipe@5 = gleam@list:map(
_pipe@4,
fun(_capture@2) ->
pretty_inner_relationship(
_capture@2,
erlang:element(3, Entity),
Indentation
)
end
),
gleam@string_builder:join(_pipe@5, <<"\n"/utf8>>)
end,
Hierarchy = begin
_pipe@6 = erlang:element(7, Entity),
_pipe@7 = gleam@option:map(
_pipe@6,
fun(_capture@3) -> pretty_hierarchy(_capture@3, Indentation) end
),
gleam@option:unwrap(_pipe@7, gleam@string_builder:new())
end,
_pipe@8 = [Keys, Attributes, Inner_relationships, Hierarchy],
_pipe@9 = gleam@list:filter(
_pipe@8,
fun(Builder) -> not gleam@string_builder:is_empty(Builder) end
),
_pipe@10 = gleam@string_builder:join(_pipe@9, <<"\n\n"/utf8>>),
gleam@string_builder:append(_pipe@10, <<"\n"/utf8>>).
-spec format(prequel@ast:module_()) -> gleam@string_builder:string_builder().
format(Module) ->
Entities = begin
_pipe = erlang:element(2, Module),
_pipe@1 = gleam@list:map(
_pipe,
fun(_capture) -> pretty_entity(_capture, 0) end
),
gleam@string_builder:join(_pipe@1, <<"\n\n"/utf8>>)
end,
Relationships = begin
_pipe@2 = erlang:element(3, Module),
_pipe@3 = gleam@list:map(_pipe@2, fun pretty_relationship/1),
gleam@string_builder:join(_pipe@3, <<"\n\n"/utf8>>)
end,
_pipe@4 = [Entities, Relationships],
_pipe@5 = gleam@list:filter(
_pipe@4,
fun(Builder) -> not gleam@string_builder:is_empty(Builder) end
),
gleam@string_builder:join(_pipe@5, <<"\n\n"/utf8>>).