-module(pears@chars). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([char/1, string/1, input/1, whitespace/0, whitespace0/0, whitespace1/0, digit/0, number/0]). -spec char(binary()) -> fun((list(binary())) -> {ok, pears:parsed(binary(), binary())} | {error, pears:parse_error(binary())}). char(C) -> pears@combinators:just(C). -spec string(binary()) -> fun((list(binary())) -> {ok, pears:parsed(binary(), binary())} | {error, pears:parse_error(binary())}). string(Str) -> fun(Input) -> S = gleam@string:to_graphemes(Str), Length = gleam@list:length(S), case gleam@list:length(Input) >= Length of true -> Candidate = gleam@list:take(Input, Length), case Candidate =:= S of true -> pears:ok(gleam@list:drop(Input, Length), Str); false -> {error, {parse_error, Input, [Str]}} end; false -> {error, {parse_error, Input, [Str]}} end end. -spec input(binary()) -> list(binary()). input(S) -> gleam@string:to_graphemes(S). -spec whitespace() -> fun((list(binary())) -> {ok, pears:parsed(binary(), binary())} | {error, pears:parse_error(binary())}). whitespace() -> pears@combinators:satisfying( fun(C) -> gleam@string:trim(C) =:= <<""/utf8>> end ). -spec whitespace0() -> fun((list(binary())) -> {ok, pears:parsed(binary(), list(binary()))} | {error, pears:parse_error(binary())}). whitespace0() -> pears@combinators:many0(whitespace()). -spec whitespace1() -> fun((list(binary())) -> {ok, pears:parsed(binary(), list(binary()))} | {error, pears:parse_error(binary())}). whitespace1() -> pears@combinators:many1(whitespace()). -spec digit() -> fun((list(binary())) -> {ok, pears:parsed(binary(), binary())} | {error, pears:parse_error(binary())}). digit() -> pears@combinators:one_of( [<<"0"/utf8>>, <<"1"/utf8>>, <<"2"/utf8>>, <<"3"/utf8>>, <<"4"/utf8>>, <<"5"/utf8>>, <<"6"/utf8>>, <<"7"/utf8>>, <<"8"/utf8>>, <<"9"/utf8>>] ). -spec number() -> fun((list(binary())) -> {ok, pears:parsed(binary(), integer())} | {error, pears:parse_error(binary())}). number() -> _pipe = pears@combinators:many1(digit()), pears@combinators:map( _pipe, fun(Digits) -> gleam@list:fold( Digits, 0, fun(Acc, Digit) -> _assert_subject = gleam@int:parse(Digit), {ok, Digit@1} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"pears/chars"/utf8>>, function => <<"number"/utf8>>, line => 65}) end, (Acc * 10) + Digit@1 end ) end ).