-module(jackson@internal@escaping). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([descape_string/1, escape_string/1]). -spec is_control_character(integer()) -> boolean(). is_control_character(Val) -> gleam@bool:guard( (Val >= 16#000) andalso (Val =< 16#001f), true, fun() -> gleam@bool:guard( (Val >= 16#007f) andalso (Val =< 16#009f), true, fun() -> gleam@bool:guard( ((Val =:= 16#061c) orelse (Val =:= 16#200e)) orelse (Val =:= 16#200f), true, fun() -> gleam@bool:guard( (Val >= 16#202a) andalso (Val =< 16#202e), true, fun() -> gleam@bool:guard( (Val >= 16#2066) andalso (Val =< 16#2069), true, fun() -> false end ) end ) end ) end ) end ). -spec string_to_ints(binary()) -> list(integer()). string_to_ints(In) -> _pipe = gleam@string:to_utf_codepoints(In), gleam@list:map(_pipe, fun gleam@string:utf_codepoint_to_int/1). -spec descape_string_loop(binary()) -> gleam@string_builder:string_builder(). descape_string_loop(In) -> Builder = gleam@string_builder:new(), case gleam@string:pop_grapheme(In) of {error, _} -> Builder; {ok, {<<"\\"/utf8>>, Next}} -> {Escaped_char, Rest@10} = case gleam@string:pop_grapheme(Next) of {ok, {<<"\""/utf8>>, Rest}} -> {<<"\""/utf8>>, Rest}; {ok, {<<"\\"/utf8>>, Rest@1}} -> {<<"\\"/utf8>>, Rest@1}; {ok, {<<"/"/utf8>>, Rest@2}} -> {<<"/"/utf8>>, Rest@2}; {ok, {<<"b"/utf8>>, Rest@3}} -> {<<"\x{0008}"/utf8>>, Rest@3}; {ok, {<<"f"/utf8>>, Rest@4}} -> {<<"\f"/utf8>>, Rest@4}; {ok, {<<"n"/utf8>>, Rest@5}} -> {<<"\n"/utf8>>, Rest@5}; {ok, {<<"r"/utf8>>, Rest@6}} -> {<<"\r"/utf8>>, Rest@6}; {ok, {<<"t"/utf8>>, Rest@7}} -> {<<"\t"/utf8>>, Rest@7}; {ok, {<<"u"/utf8>>, Rest@8}} -> case gleam@string:to_graphemes(Rest@8) of [A, B, C, D | Rest@9] -> Codepoint = begin _pipe = gleam@int:base_parse( gleam@string:concat([A, B, C, D]), 16 ), gleam@result:'try'( _pipe, fun gleam@string:utf_codepoint/1 ) end, case Codepoint of {ok, Code} -> {gleam_stdlib:utf_codepoint_list_to_string( [Code] ), gleam@string:concat(Rest@9)}; _ -> erlang:error(#{gleam_error => panic, message => <<"invalid json utf codepoint escape sequence"/utf8>>, module => <<"jackson/internal/escaping"/utf8>>, function => <<"descape_string_loop"/utf8>>, line => 128}) end; _ -> erlang:error(#{gleam_error => panic, message => <<"invalid json escape sequence"/utf8>>, module => <<"jackson/internal/escaping"/utf8>>, function => <<"descape_string_loop"/utf8>>, line => 131}) end; _ -> erlang:error(#{gleam_error => panic, message => <<"invalid json escape sequence"/utf8>>, module => <<"jackson/internal/escaping"/utf8>>, function => <<"descape_string_loop"/utf8>>, line => 133}) end, _pipe@1 = Builder, _pipe@2 = gleam@string_builder:append(_pipe@1, Escaped_char), gleam@string_builder:append_builder( _pipe@2, descape_string_loop(Rest@10) ); {ok, {Char, Rest@11}} -> _pipe@3 = Builder, _pipe@4 = gleam@string_builder:append(_pipe@3, Char), gleam@string_builder:append_builder( _pipe@4, descape_string_loop(Rest@11) ) end. -spec descape_string(binary()) -> binary(). descape_string(In) -> _pipe = descape_string_loop(In), gleam@string_builder:to_string(_pipe). -spec escape_string_loop(list(integer())) -> list(integer()). escape_string_loop(In) -> case In of [] -> []; [16#201c | Rest] -> [16#005c, 16#201c | escape_string_loop(Rest)]; [16#005c | Rest@1] -> [16#005c, 16#005c | escape_string_loop(Rest@1)]; [16#002f | Rest@2] -> [16#005c, 16#002f | escape_string_loop(Rest@2)]; [16#0008 | Rest@3] -> [16#005c, 16#0062 | escape_string_loop(Rest@3)]; [16#000c | Rest@4] -> [16#005c, 16#0066 | escape_string_loop(Rest@4)]; [16#000a | Rest@5] -> [16#005c, 16#006e | escape_string_loop(Rest@5)]; [16#000d | Rest@6] -> [16#005c, 16#0072 | escape_string_loop(Rest@6)]; [16#2b7e | Rest@7] -> [16#005c, 16#0074 | escape_string_loop(Rest@7)]; [Next_codepoint | Rest@8] -> case is_control_character(Next_codepoint) of false -> [Next_codepoint | escape_string_loop(Rest@8)]; true -> Escaped_ints = begin _pipe = gleam@int:to_base16(Next_codepoint), _pipe@1 = gleam@string:to_utf_codepoints(_pipe), gleam@list:map( _pipe@1, fun gleam@string:utf_codepoint_to_int/1 ) end, _assert_subject = case Escaped_ints of [] -> [16#0030, 16#0030, 16#0030, 16#0030]; [A] -> [16#0030, 16#0030, 16#0030, A]; [A@1, B] -> [16#0030, 16#0030, A@1, B]; [A@2, B@1, C] -> [16#0030, A@2, B@1, C]; [A@3, B@2, C@1, D] -> [A@3, B@2, C@1, D]; _ -> erlang:error(#{gleam_error => panic, message => <<"un encodable utf control character"/utf8>>, module => <<"jackson/internal/escaping"/utf8>>, function => <<"escape_string_loop"/utf8>>, line => 87}) end, [A@4, B@3, C@2, D@1] = case _assert_subject of [_, _, _, _] -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"jackson/internal/escaping"/utf8>>, function => <<"escape_string_loop"/utf8>>, line => 81}) end, [16#005c, 16#0075, A@4, B@3, C@2, D@1 | escape_string_loop(Rest@8)] end end. -spec escape_string(binary()) -> binary(). escape_string(In) -> _pipe = gleam@string:to_utf_codepoints(In), _pipe@1 = gleam@list:map(_pipe, fun gleam@string:utf_codepoint_to_int/1), _pipe@2 = escape_string_loop(_pipe@1), _pipe@3 = gleam@list:map(_pipe@2, fun gleam@string:utf_codepoint/1), _pipe@4 = gleam@result:values(_pipe@3), gleam_stdlib:utf_codepoint_list_to_string(_pipe@4).