String

parse_str : Parser(Utf8, a), Str -> Try(a, [ParsingFailure(Str), ParsingIncomplete(Str)])

Parse a Str using a Parser

color : Parser(Utf8, [Red, Green, Blue])
color = {
    one_of(
        [
            Parser.const(Red).skip(string("red")),
            Parser.const(Green).skip(string("green")),
            Parser.const(Blue).skip(string("blue")),
        ]
    )
}

expect parse_str(color, "green") == Ok(Green)
parse_str_partial : Parser(Utf8, a), Str -> Try({ val : a, input : Str }, [ParsingFailure(Str)])

Runs a parser against the start of a string, allowing the parser to consume it only partially.

- If the parser succeeds, returns the resulting value as well as the leftover input. - If the parser fails, returns Err (ParsingFailure msg)

at_sign : Parser(Utf8, [AtSign])
at_sign = Parser.const(AtSign).skip(codeunit('@'))

expect parse_str(at_sign, "@") == Ok(AtSign)
expect at_sign->parse_str_partial("@").map_ok(|r| { r.val }) == Ok(AtSign)
expect at_sign->parse_str_partial("$").is_err()
parse_utf8 : Parser(Utf8, a), Utf8 -> Try(a, [ParsingFailure(Str), ParsingIncomplete(Utf8)])

Runs a parser against a string, requiring the parser to consume it fully.

- If the parser succeeds, returns Ok a - If the parser fails, returns Err (ParsingFailure Str) - If the parser succeeds but does not consume the full string, returns Err (ParsingIncomplete (List U8))

parse_utf8_partial : Parser(Utf8, a), Utf8 -> Try({ val : a, input : Utf8 }, [ParsingFailure(Str)])

Runs a parser against the start of a list of scalars, allowing the parser to consume it only partially.

codeunit_satisfies : (U8 -> Bool) -> Parser(Utf8, U8)
is_digit : U8 -> Bool
is_digit = |b| { b >= '0' and b <= '9' }

expect codeunit_satisfies->parse_str(is_digit, "0") == Ok('0')
expect codeunit_satisfies->parse_str(is_digit, "*").is_err()
codeunit : U8 -> Parser(Utf8, U8)
at_sign : Parser(Utf8, [AtSign])
at_sign = Parser.const(AtSign).skip(codeunit('@'))

expect at_sign->parse_str("@") == Ok(AtSign)
expect at_sign->parse_str_partial("$").is_err()
string : Str -> Parser(Utf8, Str)

Parse the given Str

expect string("Foo")->parse_str("Foo") == Ok("Foo")
expect string("Foo")->parse_str("Bar").is_err()
any_codeunit : Parser(Utf8, U8)

Matches any U8 codeunit

expect parse_str(any_codeunit, "a") == Ok('a')
expect parse_str(any_codeunit, "$") == Ok('$')
any_thing : Parser(Utf8, Utf8)

Matches any Utf8 and consumes all the input without fail.

expect {
    bytes = "consumes all the input".to_utf8()
    any_thing.parse(bytes, List.is_empty) == Ok(bytes)
}
digit : Parser(Utf8, U64)
expect digit->parse_str("0") == Ok(0)
expect digit->parse_str("not a digit").is_err()
digits : Parser(Utf8, U64)

Parse a sequence of digits into a U64, accepting leading zeroes

expect digits->parse_str("0123") == Ok(123)
expect digits->parse_str("not a digit").is_err()
one_of : List(Parser(Utf8, a)) -> Parser(Utf8, a)

Try a bunch of different parsers.

The first parser which is tried is the one at the front of the list, and the next one is tried until one succeeds or the end of the list was reached.

bool_parser : Parser(Utf8, Bool)
bool_parser = {
    one_of([string("true"), string("false")])
    .map(|x| { x == "true" })
}

expect bool_parser->parse_str("true") == Ok(Bool.True)
expect bool_parser->parse_str("false") == Ok(Bool.False)
expect bool_parser->parse_str("not a bool").is_err()