Packages

A tiny GPX builder for Gleam

Current section

Files

Jump to
gpxb src gpxb.erl
Raw

src/gpxb.erl

-module(gpxb).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([render/1]).
-export_type([gpx/0, coordinate/0, waypoint/0, route/0, track/0, track_segment/0, time/0, metadata/0, person/0, link/0]).
-type gpx() :: {gpx,
gleam@option:option(metadata()),
list(waypoint()),
list(route()),
list(track())}.
-type coordinate() :: {coordinate, float(), float()}.
-type waypoint() :: {waypoint,
coordinate(),
gleam@option:option(binary()),
gleam@option:option(binary()),
gleam@option:option(time())}.
-type route() :: {route,
gleam@option:option(binary()),
gleam@option:option(binary()),
gleam@option:option(binary()),
list(link()),
list(waypoint())}.
-type track() :: {track,
gleam@option:option(binary()),
gleam@option:option(binary()),
gleam@option:option(binary()),
list(link()),
list(track_segment())}.
-type track_segment() :: {track_segment, list(waypoint())}.
-type time() :: {time,
integer(),
integer(),
integer(),
integer(),
integer(),
integer(),
integer()}.
-type metadata() :: {metadata,
gleam@option:option(binary()),
gleam@option:option(binary()),
gleam@option:option(person())}.
-type person() :: {person,
gleam@option:option(binary()),
gleam@option:option(binary()),
gleam@option:option(link())}.
-type link() :: {link,
binary(),
gleam@option:option(binary()),
gleam@option:option(binary())}.
-spec text_elem(binary(), binary()) -> xmb:xml().
text_elem(Tag, Child) ->
xmb:x(Tag, [], [xmb:text(Child)]).
-spec map_push(list(MCQ), gleam@option:option(MCS), fun((MCS) -> MCQ)) -> list(MCQ).
map_push(Items, Item, Transform) ->
case Item of
none ->
Items;
{some, Item@1} ->
[Transform(Item@1) | Items]
end.
-spec link(link()) -> xmb:xml().
link(Link) ->
xmb:x(
<<"link"/utf8>>,
[{<<"href"/utf8>>, erlang:element(2, Link)}],
begin
_pipe = [],
_pipe@1 = map_push(
_pipe,
erlang:element(4, Link),
fun(_capture) -> text_elem(<<"type"/utf8>>, _capture) end
),
map_push(
_pipe@1,
erlang:element(3, Link),
fun(_capture@1) -> text_elem(<<"text"/utf8>>, _capture@1) end
)
end
).
-spec person(binary(), person()) -> xmb:xml().
person(Tag, Author) ->
xmb:x(
Tag,
[],
begin
_pipe = [],
_pipe@1 = map_push(_pipe, erlang:element(4, Author), fun link/1),
_pipe@2 = map_push(
_pipe@1,
erlang:element(3, Author),
fun(_capture) -> text_elem(<<"email"/utf8>>, _capture) end
),
map_push(
_pipe@2,
erlang:element(2, Author),
fun(_capture@1) -> text_elem(<<"name"/utf8>>, _capture@1) end
)
end
).
-spec time(time()) -> xmb:xml().
time(Time) ->
I@1 = fun(I) -> _pipe = I,
_pipe@1 = gleam@int:to_string(_pipe),
gleam@string:pad_left(_pipe@1, 2, <<"0"/utf8>>) end,
Timestamp = <<<<<<<<<<<<<<<<<<<<<<<<<<(I@1(erlang:element(2, Time)))/binary,
"-"/utf8>>/binary,
(I@1(
erlang:element(3, Time)
))/binary>>/binary,
"-"/utf8>>/binary,
(I@1(erlang:element(4, Time)))/binary>>/binary,
"T"/utf8>>/binary,
(I@1(erlang:element(5, Time)))/binary>>/binary,
":"/utf8>>/binary,
(I@1(erlang:element(6, Time)))/binary>>/binary,
":"/utf8>>/binary,
(I@1(erlang:element(7, Time)))/binary>>/binary,
"."/utf8>>/binary,
(gleam@string:pad_left(
gleam@int:to_string(erlang:element(8, Time) rem 1000),
4,
<<"0"/utf8>>
))/binary>>/binary,
"Z"/utf8>>,
xmb:x(<<"time"/utf8>>, [], [xmb:text(Timestamp)]).
-spec waypoint(binary(), waypoint()) -> xmb:xml().
waypoint(Tag, Waypoint) ->
xmb:x(
Tag,
[{<<"latitude"/utf8>>,
gleam@float:to_string(
erlang:element(2, erlang:element(2, Waypoint))
)},
{<<"longitude"/utf8>>,
gleam@float:to_string(
erlang:element(3, erlang:element(2, Waypoint))
)}],
begin
_pipe = [],
_pipe@1 = map_push(_pipe, erlang:element(5, Waypoint), fun time/1),
_pipe@2 = map_push(
_pipe@1,
erlang:element(4, Waypoint),
fun(_capture) -> text_elem(<<"desc"/utf8>>, _capture) end
),
map_push(
_pipe@2,
erlang:element(3, Waypoint),
fun(_capture@1) -> text_elem(<<"name"/utf8>>, _capture@1) end
)
end
).
-spec route(route()) -> xmb:xml().
route(Route) ->
xmb:x(
<<"rte"/utf8>>,
[],
begin
_pipe = [gleam@list:map(erlang:element(5, Route), fun link/1),
gleam@list:map(
erlang:element(6, Route),
fun(_capture) -> waypoint(<<"rtept"/utf8>>, _capture) end
)],
_pipe@1 = gleam@list:concat(_pipe),
_pipe@2 = map_push(
_pipe@1,
erlang:element(4, Route),
fun(_capture@1) -> text_elem(<<"src"/utf8>>, _capture@1) end
),
_pipe@3 = map_push(
_pipe@2,
erlang:element(3, Route),
fun(_capture@2) -> text_elem(<<"desc"/utf8>>, _capture@2) end
),
map_push(
_pipe@3,
erlang:element(2, Route),
fun(_capture@3) -> text_elem(<<"name"/utf8>>, _capture@3) end
)
end
).
-spec track_segment(track_segment()) -> xmb:xml().
track_segment(Segment) ->
xmb:x(
<<"trkseg"/utf8>>,
[],
gleam@list:map(
erlang:element(2, Segment),
fun(_capture) -> waypoint(<<"trkpt"/utf8>>, _capture) end
)
).
-spec track(track()) -> xmb:xml().
track(Track) ->
xmb:x(
<<"trk"/utf8>>,
[],
begin
_pipe = [gleam@list:map(erlang:element(5, Track), fun link/1),
gleam@list:map(erlang:element(6, Track), fun track_segment/1)],
_pipe@1 = gleam@list:concat(_pipe),
_pipe@2 = map_push(
_pipe@1,
erlang:element(4, Track),
fun(_capture) -> text_elem(<<"src"/utf8>>, _capture) end
),
_pipe@3 = map_push(
_pipe@2,
erlang:element(3, Track),
fun(_capture@1) -> text_elem(<<"desc"/utf8>>, _capture@1) end
),
map_push(
_pipe@3,
erlang:element(2, Track),
fun(_capture@2) -> text_elem(<<"name"/utf8>>, _capture@2) end
)
end
).
-spec render(gpx()) -> gleam@string_builder:string_builder().
render(Gpx) ->
Children = begin
_pipe = [gleam@list:map(
erlang:element(3, Gpx),
fun(_capture) -> waypoint(<<"wpt"/utf8>>, _capture) end
),
gleam@list:map(erlang:element(4, Gpx), fun route/1),
gleam@list:map(erlang:element(5, Gpx), fun track/1)],
_pipe@1 = gleam@list:concat(_pipe),
map_push(_pipe@1, erlang:element(2, Gpx), fun(Metadata) -> _pipe@2 = [],
_pipe@3 = map_push(
_pipe@2,
erlang:element(4, Metadata),
fun(_capture@1) -> person(<<"author"/utf8>>, _capture@1) end
),
_pipe@4 = map_push(
_pipe@3,
erlang:element(3, Metadata),
fun(_capture@2) ->
text_elem(<<"desc"/utf8>>, _capture@2)
end
),
_pipe@5 = map_push(
_pipe@4,
erlang:element(2, Metadata),
fun(_capture@3) ->
text_elem(<<"name"/utf8>>, _capture@3)
end
),
xmb:x(<<"metadata"/utf8>>, [], _pipe@5) end)
end,
Gpx@1 = xmb:x(
<<"gpx"/utf8>>,
[{<<"version"/utf8>>, <<"1.1"/utf8>>},
{<<"creator"/utf8>>, <<"gleam-gpxb"/utf8>>},
{<<"xmlns"/utf8>>, <<"http://www.topografix.com/GPX/1/1"/utf8>>}],
Children
),
xmb:render([Gpx@1]).