-module(mon@combinators). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([tag/1, take_while/1, take_while_m_n/3, map_res/2]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. -file("src/mon/combinators.gleam", 7). ?DOC(" Match an exact pattern.\n"). -spec tag(binary()) -> fun((binary()) -> {ok, {binary(), binary()}} | {error, mon:parse_error(binary())}). tag(Tag) -> fun(Input) -> case gleam_stdlib:string_starts_with(Input, Tag) of true -> {ok, {gleam@string:drop_start(Input, string:length(Tag)), Tag}}; false -> {error, {parse_error, Input, tag}} end end. -file("src/mon/combinators.gleam", 17). ?DOC(" Match graphemes while the given predicate returns `True`.\n"). -spec take_while(fun((binary()) -> boolean())) -> fun((binary()) -> {ok, {binary(), binary()}} | {error, mon:parse_error(binary())}). take_while(Predicate) -> fun(Input) -> {ok, begin _pipe = Input, _pipe@1 = gleam@string:to_graphemes(_pipe), gleam@list:fold_until( _pipe@1, {Input, <<""/utf8>>}, fun(Acc, Grapheme) -> {Input@1, Output} = Acc, case Predicate(Grapheme) of true -> {continue, {gleam@string:drop_start(Input@1, 1), <>}}; false -> {stop, Acc} end end ) end} end. -file("src/mon/combinators.gleam", 35). ?DOC( " Like `take_while`, but the length of the output must be in the range\n" " specified by `m` and `n` (inclusive).\n" ). -spec take_while_m_n(integer(), integer(), fun((binary()) -> boolean())) -> fun((binary()) -> {ok, {binary(), binary()}} | {error, mon:parse_error(binary())}). take_while_m_n(M, N, Predicate) -> fun(Input) -> _pipe = Input, _pipe@1 = gleam@string:to_graphemes(_pipe), _pipe@2 = gleam@list:fold_until( _pipe@1, {Input, <<""/utf8>>, M, N}, fun(Acc, Grapheme) -> {Input@1, Output, M@1, N@1} = Acc, case gleam@bool:'and'(Predicate(Grapheme), N@1 > 0) of true -> {continue, {gleam@string:drop_start(Input@1, 1), <>, M@1 - 1, N@1 - 1}}; _ -> {stop, Acc} end end ), (fun(Acc@1) -> {Input@2, Output@1, M@2, _} = Acc@1, case M@2 =< 0 of true -> {ok, {Input@2, Output@1}}; false -> {error, {parse_error, Input@2, take_while_mn}} end end)(_pipe@2) end. -file("src/mon/combinators.gleam", 67). ?DOC(" Apply a `Result` returning function over the result of a `Parser`.\n"). -spec map_res( fun((EYE) -> {ok, {EYE, EYF}} | {error, mon:parse_error(EYE)}), fun((EYF) -> {ok, EYI} | {error, any()}) ) -> fun((EYE) -> {ok, {EYE, EYI}} | {error, mon:parse_error(EYE)}). map_res(Parser, Fun) -> fun(Input) -> case Parser(Input) of {ok, {Input@1, Output}} -> case Fun(Output) of {ok, Output@1} -> {ok, {Input@1, Output@1}}; {error, _} -> {error, {parse_error, Input@1, map_res}} end; {error, E} -> {error, E} end end.