-module(lustre@element). -compile([no_auto_import, nowarn_unused_vars]). -export([element/3, namespaced/4, text/1, map/2, to_string_builder/1, to_string/1]). -export_type([element/1]). -opaque element(FGN) :: {text, binary()} | {element, binary(), list(lustre@attribute:attribute(FGN)), list(element(FGN))} | {element_ns, binary(), list(lustre@attribute:attribute(FGN)), list(element(FGN)), binary()}. -spec element( binary(), list(lustre@attribute:attribute(FGO)), list(element(FGO)) ) -> element(FGO). element(Tag, Attrs, Children) -> {element, Tag, Attrs, Children}. -spec namespaced( binary(), binary(), list(lustre@attribute:attribute(FGU)), list(element(FGU)) ) -> element(FGU). namespaced(Namespace, Tag, Attrs, Children) -> {element_ns, Tag, Attrs, Children, Namespace}. -spec text(binary()) -> element(any()). text(Content) -> {text, Content}. -spec escape(binary(), binary()) -> binary(). escape(Escaped, Content) -> case gleam@string:pop_grapheme(Content) of {ok, {<<"<"/utf8>>, Xs}} -> escape(<>, Xs); {ok, {<<">"/utf8>>, Xs@1}} -> escape(<>, Xs@1); {ok, {<<"&"/utf8>>, Xs@2}} -> escape(<>, Xs@2); {ok, {<<"\""/utf8>>, Xs@3}} -> escape(<>, Xs@3); {ok, {<<"'"/utf8>>, Xs@4}} -> escape(<>, Xs@4); {ok, {X, Xs@5}} -> escape(<>, Xs@5); {error, _} -> <> end. -spec map(element(FHC), fun((FHC) -> FHE)) -> element(FHE). map(Element, F) -> case Element of {text, Content} -> {text, Content}; {element, Tag, Attrs, Children} -> {element, Tag, gleam@list:map( Attrs, fun(_capture) -> lustre@attribute:map(_capture, F) end ), gleam@list:map( Children, fun(_capture@1) -> map(_capture@1, F) end )}; {element_ns, Tag@1, Attrs@1, Children@1, Namespace} -> {element_ns, Tag@1, gleam@list:map( Attrs@1, fun(_capture@2) -> lustre@attribute:map(_capture@2, F) end ), gleam@list:map( Children@1, fun(_capture@3) -> map(_capture@3, F) end ), Namespace} end. -spec attrs_to_string_builder( gleam@string_builder:string_builder(), list(lustre@attribute:attribute(any())) ) -> gleam@string_builder:string_builder(). attrs_to_string_builder(Html, Attrs) -> gleam@list:fold( Attrs, Html, fun(Html@1, Attr) -> gleam@string_builder:append_builder( Html@1, lustre@attribute:to_string_builder(Attr) ) end ). -spec children_to_string_builder( gleam@string_builder:string_builder(), list(element(any())) ) -> gleam@string_builder:string_builder(). children_to_string_builder(Html, Children) -> gleam@list:fold( Children, Html, fun(Html@1, Child) -> gleam@string_builder:append_builder( Html@1, to_string_builder(Child) ) end ). -spec to_string_builder(element(any())) -> gleam@string_builder:string_builder(). to_string_builder(Element) -> case Element of {text, Content} -> gleam@string_builder:from_string(escape(<<""/utf8>>, Content)); {element, Tag, Attrs, Children} -> _pipe = gleam@string_builder:from_string(<<"<"/utf8, Tag/binary>>), _pipe@1 = attrs_to_string_builder(_pipe, Attrs), _pipe@2 = gleam@string_builder:append(_pipe@1, <<">"/utf8>>), _pipe@3 = children_to_string_builder(_pipe@2, Children), gleam@string_builder:append( _pipe@3, <<<<">/binary, ">"/utf8>> ); {element_ns, Tag@1, Attrs@1, Children@1, Namespace} -> _pipe@4 = gleam@string_builder:from_string( <<"<"/utf8, Tag@1/binary>> ), _pipe@5 = attrs_to_string_builder(_pipe@4, Attrs@1), _pipe@6 = gleam@string_builder:append( _pipe@5, <<<<" xmlns=\""/utf8, Namespace/binary>>/binary, "\""/utf8>> ), _pipe@7 = gleam@string_builder:append(_pipe@6, <<">"/utf8>>), _pipe@8 = children_to_string_builder(_pipe@7, Children@1), gleam@string_builder:append( _pipe@8, <<<<">/binary, ">"/utf8>> ) end. -spec to_string(element(any())) -> binary(). to_string(Element) -> _pipe = to_string_builder(Element), gleam@string_builder:to_string(_pipe).