Using Angstrom with Eio?

In the Eio.Buf_read docs it says:

This module provides fairly efficient non-backtracking parsers. It is modelled on Angstrom’s API, and you should use that if backtracking is needed.

I have in hand a Cohttp.Body.t which is an alias for Eio.Flow.source_ty Eio.Resource.t and want to use Angstrom to parse a sequence of JSON objects returned in the body but I’m unclear how an Angstrom parser should consume and Eio.Resource.

When Angstrom.Buffered wants more data, use Eio.Flow.single_read to get some for it.

However, I suspect you don’t need a backtracking parser to parse JSON.

1 Like

Ok - I’ve written a JSON parser using Eio.Buf_read combinators but I’m running into problems with Eio.Buf_read.seq.

To simplify things I tried using seq with a simple parser:

let whitespace =
  skip_while (function
    | '\x20' | '\x0a' | '\x0d' | '\x09' -> true
    | _ -> false)
;;

let p = whitespace *> any_char <* whitespace
;;

I can use this successfully with the following:

Eio.Buf_read.(parse ~max_size:Int.max_int @@ p) @@ Cohttp_eio.Body.of_string {|    c |};;
- : (char, [> `Msg of string ]) result = Ok 'c'

But this fails:

Eio.Buf_read.(parse ~max_size:Int.max_int @@ seq p) @@ Cohttp_eio.Body.of_string {|a b c d e|}
- : (char Seq.t, [> `Msg of string ]) result =
Error (`Msg "Unexpected data after parsing (at offset 0)")

What am I doing wrong?

You need to do something with the sequence. Since you didn’t read anything from it, no data was actually parsed.

See e.g. this example:

2 Likes

Ah ok! Thanks so much for your help!!