-module(kdleam@string). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/kdleam/string.gleam"). -export([parse_identifier_string/1, parse_raw_string/1, parse_quoted_string/1, parse_string_if_available/1, parse_string/1]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC(false). -file("src/kdleam/string.gleam", 140). ?DOC(false). -spec check_keyword( binary(), kdleam@scanner:scanner(), kdleam@scanner:scanner() ) -> {ok, {gleam@option:option(binary()), kdleam@scanner:scanner()}} | {error, kdleam@error:kdl_error()}. check_keyword(Value, Start, Next) -> case kdleam@scanner:is_reserved_keyword(Value) of true -> {error, kdleam@scanner:make_error(Start, bare_keyword)}; false -> {ok, {{some, Value}, Next}} end. -file("src/kdleam/string.gleam", 126). ?DOC(false). -spec collect_chars(kdleam@scanner:scanner(), list(binary())) -> {list(binary()), kdleam@scanner:scanner()}. collect_chars(S, Acc) -> case kdleam@scanner:peek(S) of {some, Ch} -> case kdleam@scanner:is_identifier_char(Ch) of true -> {_, Next} = kdleam@scanner:advance(S), collect_chars(Next, [Ch | Acc]); false -> {Acc, S} end; _ -> {Acc, S} end. -file("src/kdleam/string.gleam", 114). ?DOC(false). -spec collect_identifier_continue(kdleam@scanner:scanner(), list(binary())) -> {ok, {gleam@option:option(binary()), kdleam@scanner:scanner()}} | {error, kdleam@error:kdl_error()}. collect_identifier_continue(S, Rev_prefix) -> {Chars, Next} = collect_chars(S, Rev_prefix), Value = begin _pipe = Chars, _pipe@1 = lists:reverse(_pipe), kdleam@scanner:join(_pipe@1) end, case Value =:= <<""/utf8>> of true -> {ok, {none, S}}; false -> check_keyword(Value, S, Next) end. -file("src/kdleam/string.gleam", 65). ?DOC(false). -spec collect_signed_or_dotted( kdleam@scanner:scanner(), binary(), boolean(), boolean() ) -> {ok, {gleam@option:option(binary()), kdleam@scanner:scanner()}} | {error, kdleam@error:kdl_error()}. collect_signed_or_dotted(S, First, Is_sign, Is_dot) -> {_, S1} = kdleam@scanner:advance(S), case {Is_sign, kdleam@scanner:peek(S1)} of {true, {some, Ch2}} -> case (kdleam@scanner:is_identifier_char(Ch2) andalso not kdleam@scanner:is_ascii_digit( Ch2 )) andalso (Ch2 /= <<"."/utf8>>) of true -> collect_identifier_continue(S1, [First]); false -> case Ch2 =:= <<"."/utf8>> of true -> {_, S2} = kdleam@scanner:advance(S1), collect_identifier_continue( S2, [<<"."/utf8>>, First] ); false -> check_keyword(First, S, S1) end end; {true, _} -> check_keyword(First, S, S1); {false, _} -> case Is_dot of true -> case kdleam@scanner:peek(S1) of {some, Ch2@1} -> case kdleam@scanner:is_identifier_char(Ch2@1) andalso not kdleam@scanner:is_ascii_digit(Ch2@1) of true -> collect_identifier_continue(S1, [First]); false -> check_keyword(First, S, S1) end; none -> check_keyword(First, S, S1) end; false -> {ok, {none, S}} end end. -file("src/kdleam/string.gleam", 108). ?DOC(false). -spec collect_identifier(kdleam@scanner:scanner()) -> {ok, {gleam@option:option(binary()), kdleam@scanner:scanner()}} | {error, kdleam@error:kdl_error()}. collect_identifier(S) -> collect_identifier_continue(S, []). -file("src/kdleam/string.gleam", 40). ?DOC(false). -spec parse_identifier_string(kdleam@scanner:scanner()) -> {ok, {gleam@option:option(binary()), kdleam@scanner:scanner()}} | {error, kdleam@error:kdl_error()}. parse_identifier_string(S) -> case kdleam@scanner:peek(S) of none -> {ok, {none, S}}; {some, Ch} -> case kdleam@scanner:is_identifier_char(Ch) of false -> {ok, {none, S}}; true -> Is_sign = (Ch =:= <<"+"/utf8>>) orelse (Ch =:= <<"-"/utf8>>), Is_dot = Ch =:= <<"."/utf8>>, Is_digit = kdleam@scanner:is_ascii_digit(Ch), case Is_digit of true -> {ok, {none, S}}; false -> case Is_sign orelse Is_dot of false -> collect_identifier(S); true -> collect_signed_or_dotted( S, Ch, Is_sign, Is_dot ) end end end end. -file("src/kdleam/string.gleam", 521). ?DOC(false). -spec consume_n(kdleam@scanner:scanner(), integer()) -> kdleam@scanner:scanner(). consume_n(S, N) -> case N =< 0 of true -> S; false -> {_, Next} = kdleam@scanner:advance(S), consume_n(Next, N - 1) end. -file("src/kdleam/string.gleam", 507). ?DOC(false). -spec consume_raw_closer( kdleam@scanner:scanner(), list(binary()), kdleam@scanner:line_form() ) -> kdleam@scanner:scanner(). consume_raw_closer(S, Hashes, Form) -> Count = erlang:length(Hashes) + case Form of multiline -> 3; single_line -> 1 end, consume_n(S, Count). -file("src/kdleam/string.gleam", 498). ?DOC(false). -spec hashes_match(kdleam@scanner:scanner(), integer(), list(binary())) -> boolean(). hashes_match(S, Pos, Hashes) -> case Hashes of [] -> true; [<<"#"/utf8>> | Rest] -> (kdleam@scanner:at(erlang:element(3, S), Pos) =:= {some, <<"#"/utf8>>}) andalso hashes_match(S, Pos + 1, Rest); _ -> false end. -file("src/kdleam/string.gleam", 479). ?DOC(false). -spec raw_closer_at( kdleam@scanner:scanner(), list(binary()), kdleam@scanner:line_form() ) -> boolean(). raw_closer_at(S, Hashes, Form) -> Offset = case Form of multiline -> 3; single_line -> 1 end, case Form of multiline -> (((kdleam@scanner:peek(S) =:= {some, <<"\""/utf8>>}) andalso (kdleam@scanner:peek_next( S ) =:= {some, <<"\""/utf8>>})) andalso (kdleam@scanner:at( erlang:element(3, S), erlang:element(4, S) + 2 ) =:= {some, <<"\""/utf8>>})) andalso hashes_match(S, erlang:element(4, S) + Offset, Hashes); single_line -> hashes_match(S, erlang:element(4, S) + Offset, Hashes) end. -file("src/kdleam/string.gleam", 447). ?DOC(false). -spec parse_raw_body( kdleam@scanner:scanner(), list(binary()), kdleam@scanner:line_form(), list(binary()) ) -> {ok, {gleam@option:option(binary()), kdleam@scanner:scanner()}} | {error, kdleam@error:kdl_error()}. parse_raw_body(S, Hashes, Form, Acc) -> case kdleam@scanner:peek(S) of none -> {error, kdleam@scanner:make_error(S, unclosed_string)}; {some, <<"\""/utf8>>} -> case raw_closer_at(S, Hashes, Form) of true -> Next = consume_raw_closer(S, Hashes, Form), Value = begin _pipe = Acc, _pipe@1 = lists:reverse(_pipe), kdleam@scanner:join(_pipe@1) end, {ok, {{some, Value}, Next}}; false -> {_, Next@1} = kdleam@scanner:advance(S), parse_raw_body(Next@1, Hashes, Form, [<<"\""/utf8>> | Acc]) end; {some, Ch} -> case (Form =:= single_line) andalso kdleam@scanner:is_newline(Ch) of true -> {error, kdleam@scanner:make_error(S, unclosed_string)}; false -> {_, Next@2} = kdleam@scanner:advance(S), parse_raw_body(Next@2, Hashes, Form, [Ch | Acc]) end end. -file("src/kdleam/string.gleam", 531). ?DOC(false). -spec consume_whitespace_escape(kdleam@scanner:scanner()) -> kdleam@scanner:scanner(). consume_whitespace_escape(S) -> case kdleam@scanner:peek(S) of {some, Ch} -> case kdleam@scanner:is_unicode_space(Ch) of true -> {_, Next} = kdleam@scanner:advance(S), consume_whitespace_escape(Next); false -> case kdleam@scanner:is_newline(Ch) of true -> {_, Next@1} = kdleam@scanner:consume_newline(S), consume_whitespace_escape(Next@1); false -> S end end; _ -> S end. -file("src/kdleam/string.gleam", 248). ?DOC(false). -spec valid_unicode_hex(binary()) -> boolean(). valid_unicode_hex(Hex) -> Chars = gleam@string:to_graphemes(Hex), Len = erlang:length(Chars), ((Len > 0) andalso (Len =< 6)) andalso gleam@list:all( Chars, fun kdleam@scanner:is_hex_digit/1 ). -file("src/kdleam/string.gleam", 254). ?DOC(false). -spec collect_until(kdleam@scanner:scanner(), binary(), list(binary())) -> {binary(), kdleam@scanner:scanner()}. collect_until(S, Delimiter, Acc) -> case kdleam@scanner:peek(S) of {some, Ch} -> case Ch /= Delimiter of true -> {_, Next} = kdleam@scanner:advance(S), collect_until(Next, Delimiter, [Ch | Acc]); false -> {begin _pipe = Acc, _pipe@1 = lists:reverse(_pipe), kdleam@scanner:join(_pipe@1) end, S} end; _ -> {begin _pipe@2 = Acc, _pipe@3 = lists:reverse(_pipe@2), kdleam@scanner:join(_pipe@3) end, S} end. -file("src/kdleam/string.gleam", 229). ?DOC(false). -spec parse_unicode_escape(kdleam@scanner:scanner()) -> {ok, {binary(), kdleam@scanner:scanner()}} | {error, kdleam@error:kdl_error()}. parse_unicode_escape(S) -> {_, S1} = kdleam@scanner:advance(S), gleam@result:'try'( kdleam@scanner:expect(S1, <<"{"/utf8>>), fun(S2) -> {Hex, S3} = collect_until(S2, <<"}"/utf8>>, []), gleam@result:'try'( kdleam@scanner:expect(S3, <<"}"/utf8>>), fun(S4) -> case valid_unicode_hex(Hex) of false -> {error, kdleam@scanner:make_error( S, invalid_unicode_escape )}; true -> case gleam@int:base_parse(Hex, 16) of {ok, I} -> case gleam@string:utf_codepoint(I) of {ok, Cp} -> {ok, {gleam_stdlib:utf_codepoint_list_to_string( [Cp] ), S4}}; {error, _} -> {error, kdleam@scanner:make_error( S, invalid_unicode_escape )} end; {error, _} -> {error, kdleam@scanner:make_error( S, invalid_unicode_escape )} end end end ) end ). -file("src/kdleam/string.gleam", 224). ?DOC(false). -spec esc(binary(), kdleam@scanner:scanner()) -> {ok, {binary(), kdleam@scanner:scanner()}} | {error, kdleam@error:kdl_error()}. esc(Value, S) -> {_, Next} = kdleam@scanner:advance(S), {ok, {Value, Next}}. -file("src/kdleam/string.gleam", 202). ?DOC(false). -spec parse_escape(kdleam@scanner:scanner()) -> {ok, {binary(), kdleam@scanner:scanner()}} | {error, kdleam@error:kdl_error()}. parse_escape(S) -> case kdleam@scanner:peek(S) of {some, <<"n"/utf8>>} -> esc(<<"\n"/utf8>>, S); {some, <<"r"/utf8>>} -> esc(<<"\r"/utf8>>, S); {some, <<"t"/utf8>>} -> esc(<<"\t"/utf8>>, S); {some, <<"b"/utf8>>} -> esc(<<"\x{0008}"/utf8>>, S); {some, <<"f"/utf8>>} -> esc(<<"\x{000C}"/utf8>>, S); {some, <<"\\"/utf8>>} -> esc(<<"\\"/utf8>>, S); {some, <<"\""/utf8>>} -> esc(<<"\""/utf8>>, S); {some, <<"s"/utf8>>} -> esc(<<" "/utf8>>, S); {some, <<"u"/utf8>>} -> parse_unicode_escape(S); {some, Ch} -> case kdleam@scanner:is_unicode_space(Ch) orelse kdleam@scanner:is_newline( Ch ) of true -> {ok, {<<""/utf8>>, consume_whitespace_escape(S)}}; false -> {error, kdleam@scanner:make_error(S, invalid_escape)} end; none -> {error, kdleam@scanner:make_error(S, unclosed_string)} end. -file("src/kdleam/string.gleam", 632). ?DOC(false). -spec resolve_escapes_loop( kdleam@scanner:scanner(), kdleam@scanner:scanner(), binary() ) -> {ok, binary()} | {error, kdleam@error:kdl_error()}. resolve_escapes_loop(S, Error_at, Acc) -> case kdleam@scanner:peek(S) of none -> {ok, Acc}; {some, <<"\\"/utf8>>} -> {_, S1} = kdleam@scanner:advance(S), gleam@result:'try'( parse_escape(S1), fun(Parsed) -> {Value, S2} = Parsed, resolve_escapes_loop( S2, Error_at, <> ) end ); {some, Ch} -> case kdleam@scanner:is_disallowed(Ch) of true -> {error, kdleam@scanner:make_error( Error_at, {disallowed_code_point, Ch} )}; false -> {_, Next} = kdleam@scanner:advance(S), resolve_escapes_loop( Next, Error_at, <> ) end end. -file("src/kdleam/string.gleam", 625). ?DOC(false). -spec resolve_escapes(binary(), kdleam@scanner:scanner()) -> {ok, binary()} | {error, kdleam@error:kdl_error()}. resolve_escapes(Input, Error_at) -> resolve_escapes_loop(kdleam@scanner:new(Input), Error_at, <<""/utf8>>). -file("src/kdleam/string.gleam", 621). ?DOC(false). -spec line_is_unicode_space(binary()) -> boolean(). line_is_unicode_space(Line) -> _pipe = Line, _pipe@1 = gleam@string:to_graphemes(_pipe), gleam@list:all(_pipe@1, fun kdleam@scanner:is_unicode_space/1). -file("src/kdleam/string.gleam", 575). ?DOC(false). -spec process_multiline_lines( list(binary()), binary(), kdleam@scanner:string_kind(), kdleam@scanner:scanner(), boolean(), binary() ) -> {ok, binary()} | {error, kdleam@error:kdl_error()}. process_multiline_lines(Lines, Prefix, Kind, Error_at, First, Acc) -> case Lines of [] -> {ok, Acc}; [Line | Rest] -> Next_acc = case First of true -> Acc; false -> <> end, case line_is_unicode_space(Line) of true -> process_multiline_lines( Rest, Prefix, Kind, Error_at, false, Next_acc ); false -> case gleam_stdlib:string_starts_with(Line, Prefix) of false -> {error, kdleam@scanner:make_error( Error_at, inconsistent_indentation )}; true -> Stripped = case gleam@string:split_once( Line, Prefix ) of {ok, {<<""/utf8>>, Rest@1}} -> Rest@1; _ -> Line end, gleam@result:'try'(case Kind of quoted -> resolve_escapes(Stripped, Error_at); raw -> {ok, Stripped} end, fun(Resolved) -> process_multiline_lines( Rest, Prefix, Kind, Error_at, false, <> ) end) end end end. -file("src/kdleam/string.gleam", 564). ?DOC(false). -spec last_line(list(binary()), list(binary())) -> {gleam@option:option(binary()), list(binary())}. last_line(Lines, Rev_body) -> case Lines of [] -> {none, lists:reverse(Rev_body)}; [Last] -> {{some, Last}, lists:reverse(Rev_body)}; [Line | Rest] -> last_line(Rest, [Line | Rev_body]) end. -file("src/kdleam/string.gleam", 552). ?DOC(false). -spec process_multiline( list(binary()), kdleam@scanner:string_kind(), kdleam@scanner:scanner() ) -> {ok, binary()} | {error, kdleam@error:kdl_error()}. process_multiline(Lines, Kind, Error_at) -> case last_line(Lines, []) of {none, _} -> {ok, <<""/utf8>>}; {{some, Prefix}, Body_lines} -> process_multiline_lines( Body_lines, Prefix, Kind, Error_at, true, <<""/utf8>> ) end. -file("src/kdleam/string.gleam", 380). ?DOC(false). -spec parse_multiline_raw_body_lines( kdleam@scanner:scanner(), list(binary()), list(binary()), binary() ) -> {ok, {gleam@option:option(binary()), kdleam@scanner:scanner()}} | {error, kdleam@error:kdl_error()}. parse_multiline_raw_body_lines(S, Hashes, Rev_lines, Current_line) -> case kdleam@scanner:peek(S) of none -> {error, kdleam@scanner:make_error(S, unclosed_string)}; {some, <<"\""/utf8>>} -> case raw_closer_at(S, Hashes, multiline) of true -> Next = consume_raw_closer(S, Hashes, multiline), gleam@result:'try'( process_multiline( begin _pipe = [Current_line | Rev_lines], lists:reverse(_pipe) end, raw, S ), fun(Value) -> {ok, {{some, Value}, Next}} end ); false -> {_, Next@1} = kdleam@scanner:advance(S), parse_multiline_raw_body_lines( Next@1, Hashes, Rev_lines, <> ) end; {some, Ch} -> case kdleam@scanner:is_newline(Ch) of true -> {_, Next@2} = kdleam@scanner:consume_newline(S), parse_multiline_raw_body_lines( Next@2, Hashes, [Current_line | Rev_lines], <<""/utf8>> ); false -> case kdleam@scanner:is_disallowed(Ch) of true -> {error, kdleam@scanner:make_error( S, {disallowed_code_point, Ch} )}; false -> {_, Next@3} = kdleam@scanner:advance(S), parse_multiline_raw_body_lines( Next@3, Hashes, Rev_lines, <> ) end end end. -file("src/kdleam/string.gleam", 367). ?DOC(false). -spec parse_multiline_raw_lines( kdleam@scanner:scanner(), list(binary()), list(binary()), binary() ) -> {ok, {gleam@option:option(binary()), kdleam@scanner:scanner()}} | {error, kdleam@error:kdl_error()}. parse_multiline_raw_lines(S, Hashes, Rev_lines, Current_line) -> {Had_newline, S1} = kdleam@scanner:consume_newline(S), case Had_newline of false -> {error, kdleam@scanner:make_error(S, unclosed_string)}; true -> parse_multiline_raw_body_lines(S1, Hashes, Rev_lines, Current_line) end. -file("src/kdleam/string.gleam", 437). ?DOC(false). -spec collect_hashes(kdleam@scanner:scanner(), list(binary())) -> {list(binary()), kdleam@scanner:scanner()}. collect_hashes(S, Acc) -> case kdleam@scanner:peek(S) of {some, <<"#"/utf8>>} -> {_, Next} = kdleam@scanner:advance(S), collect_hashes(Next, [<<"#"/utf8>> | Acc]); _ -> {lists:reverse(Acc), S} end. -file("src/kdleam/string.gleam", 344). ?DOC(false). -spec parse_raw_string(kdleam@scanner:scanner()) -> {ok, {gleam@option:option(binary()), kdleam@scanner:scanner()}} | {error, kdleam@error:kdl_error()}. parse_raw_string(S) -> {Hashes, After_hashes} = collect_hashes(S, []), case {kdleam@scanner:peek(After_hashes), kdleam@scanner:peek_next(After_hashes), kdleam@scanner:at( erlang:element(3, After_hashes), erlang:element(4, After_hashes) + 2 )} of {{some, <<"\""/utf8>>}, {some, <<"\""/utf8>>}, {some, <<"\""/utf8>>}} -> {_, S1} = kdleam@scanner:advance(After_hashes), {_, S2} = kdleam@scanner:advance(S1), {_, S3} = kdleam@scanner:advance(S2), parse_multiline_raw_lines(S3, Hashes, [], <<""/utf8>>); {{some, <<"\""/utf8>>}, _, _} -> {_, S1@1} = kdleam@scanner:advance(After_hashes), parse_raw_body(S1@1, Hashes, single_line, []); {_, _, _} -> {ok, {none, S}} end. -file("src/kdleam/string.gleam", 171). ?DOC(false). -spec parse_quoted_body(kdleam@scanner:scanner(), list(binary())) -> {ok, {gleam@option:option(binary()), kdleam@scanner:scanner()}} | {error, kdleam@error:kdl_error()}. parse_quoted_body(S, Acc) -> case kdleam@scanner:peek(S) of none -> {error, kdleam@scanner:make_error(S, unclosed_string)}; {some, <<"\""/utf8>>} -> {_, Next} = kdleam@scanner:advance(S), {ok, {{some, begin _pipe = Acc, _pipe@1 = lists:reverse(_pipe), kdleam@scanner:join(_pipe@1) end}, Next}}; {some, <<"\\"/utf8>>} -> {_, S1} = kdleam@scanner:advance(S), gleam@result:'try'( parse_escape(S1), fun(Result) -> {Value, S2} = Result, parse_quoted_body(S2, [Value | Acc]) end ); {some, Ch} -> case kdleam@scanner:is_newline(Ch) of true -> {error, kdleam@scanner:make_error(S, unclosed_string)}; false -> case kdleam@scanner:is_disallowed(Ch) of true -> {error, kdleam@scanner:make_error( S, {disallowed_code_point, Ch} )}; false -> {_, Next@1} = kdleam@scanner:advance(S), parse_quoted_body(Next@1, [Ch | Acc]) end end end. -file("src/kdleam/string.gleam", 282). ?DOC(false). -spec parse_multiline_quoted_lines( kdleam@scanner:scanner(), list(binary()), binary() ) -> {ok, {gleam@option:option(binary()), kdleam@scanner:scanner()}} | {error, kdleam@error:kdl_error()}. parse_multiline_quoted_lines(S, Rev_lines, Current_line) -> case {kdleam@scanner:peek(S), kdleam@scanner:peek_next(S), kdleam@scanner:at(erlang:element(3, S), erlang:element(4, S) + 2)} of {{some, <<"\""/utf8>>}, {some, <<"\""/utf8>>}, {some, <<"\""/utf8>>}} -> {_, S1} = kdleam@scanner:advance(S), {_, S2} = kdleam@scanner:advance(S1), {_, S3} = kdleam@scanner:advance(S2), gleam@result:'try'( process_multiline( begin _pipe = [Current_line | Rev_lines], lists:reverse(_pipe) end, quoted, S ), fun(Value) -> {ok, {{some, Value}, S3}} end ); {{some, <<"\\"/utf8>>}, _, _} -> {_, S1@1} = kdleam@scanner:advance(S), case kdleam@scanner:peek(S1@1) of {some, Ch} -> case kdleam@scanner:is_unicode_space(Ch) orelse kdleam@scanner:is_newline( Ch ) of true -> parse_multiline_quoted_lines( consume_whitespace_escape(S1@1), Rev_lines, Current_line ); false -> {_, S2@1} = kdleam@scanner:advance(S1@1), parse_multiline_quoted_lines( S2@1, Rev_lines, <<<>/binary, Ch/binary>> ) end; none -> {error, kdleam@scanner:make_error(S1@1, invalid_escape)} end; {none, _, _} -> {error, kdleam@scanner:make_error(S, unclosed_string)}; {{some, Ch@1}, _, _} -> case kdleam@scanner:is_newline(Ch@1) of true -> {_, Next} = kdleam@scanner:consume_newline(S), parse_multiline_quoted_lines( Next, [Current_line | Rev_lines], <<""/utf8>> ); false -> case kdleam@scanner:is_disallowed(Ch@1) of true -> {error, kdleam@scanner:make_error( S, {disallowed_code_point, Ch@1} )}; false -> {_, Next@1} = kdleam@scanner:advance(S), parse_multiline_quoted_lines( Next@1, Rev_lines, <> ) end end end. -file("src/kdleam/string.gleam", 272). ?DOC(false). -spec parse_multiline_quoted(kdleam@scanner:scanner()) -> {ok, {gleam@option:option(binary()), kdleam@scanner:scanner()}} | {error, kdleam@error:kdl_error()}. parse_multiline_quoted(S) -> {Had_newline, S1} = kdleam@scanner:consume_newline(S), case Had_newline of false -> {error, kdleam@scanner:make_error(S, unclosed_string)}; true -> parse_multiline_quoted_lines(S1, [], <<""/utf8>>) end. -file("src/kdleam/string.gleam", 152). ?DOC(false). -spec parse_quoted_string(kdleam@scanner:scanner()) -> {ok, {gleam@option:option(binary()), kdleam@scanner:scanner()}} | {error, kdleam@error:kdl_error()}. parse_quoted_string(S) -> case kdleam@scanner:peek(S) of {some, <<"\""/utf8>>} -> {_, S1} = kdleam@scanner:advance(S), case {kdleam@scanner:peek(S1), kdleam@scanner:peek_next(S1)} of {{some, <<"\""/utf8>>}, {some, <<"\""/utf8>>}} -> {_, S2} = kdleam@scanner:advance(S1), {_, S3} = kdleam@scanner:advance(S2), parse_multiline_quoted(S3); {_, _} -> parse_quoted_body(S1, []) end; _ -> {ok, {none, S}} end. -file("src/kdleam/string.gleam", 23). ?DOC(false). -spec parse_string_if_available(kdleam@scanner:scanner()) -> {ok, {gleam@option:option(binary()), kdleam@scanner:scanner()}} | {error, kdleam@error:kdl_error()}. parse_string_if_available(S) -> gleam@result:'try'(parse_quoted_string(S), fun(Quoted) -> case Quoted of {{some, _}, _} -> {ok, Quoted}; {none, _} -> gleam@result:'try'( parse_raw_string(S), fun(Raw) -> case Raw of {{some, _}, _} -> {ok, Raw}; {none, _} -> parse_identifier_string(S) end end ) end end). -file("src/kdleam/string.gleam", 10). ?DOC(false). -spec parse_string(kdleam@scanner:scanner()) -> {ok, {binary(), kdleam@scanner:scanner()}} | {error, kdleam@error:kdl_error()}. parse_string(S) -> gleam@result:'try'(parse_string_if_available(S), fun(Maybe) -> case Maybe of {{some, Value}, Next} -> {ok, {Value, Next}}; {none, Next@1} -> case kdleam@scanner:peek(Next@1) of {some, Ch} -> {error, kdleam@scanner:make_error( Next@1, {unexpected_char, Ch} )}; none -> {error, kdleam@scanner:make_error( Next@1, unexpected_eof )} end end end).