# Using Angstrom with Eio?

**URL:** <https://discuss.ocaml.org/t/using-angstrom-with-eio/15242>\
**Category:** Learning\
**Tags:** angstrom, eio\
**Created:** [September 4, 2024, 1:18pm UTC](https://discuss.ocaml.org/t/using-angstrom-with-eio/15242 "2024-09-04T13:18:04Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![enetsee](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/enetsee/32/1041_2.png) [@enetsee](https://discuss.ocaml.org/u/enetsee)\
**Post date:** [September 4, 2024, 1:18pm UTC](https://discuss.ocaml.org/t/using-angstrom-with-eio/15242/1 "2024-09-04T13:18:04Z")

</div>

In the [`Eio.Buf_read` docs](https://ocaml-multicore.github.io/eio/eio/Eio/Buf_read/index.html) 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`.

---

<div class="post-metadata">

**Author:** ![talex5](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/talex5/32/353_2.png) [@talex5](https://discuss.ocaml.org/u/talex5)\
**Post date:** [September 4, 2024, 1:56pm UTC](https://discuss.ocaml.org/t/using-angstrom-with-eio/15242/2 "2024-09-04T13:56:04Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![enetsee](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/enetsee/32/1041_2.png) [@enetsee](https://discuss.ocaml.org/u/enetsee)\
**Post date:** [September 5, 2024, 10:23am UTC](https://discuss.ocaml.org/t/using-angstrom-with-eio/15242/3 "2024-09-05T10:23:50Z")

</div>

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:

```auto
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:

```auto
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:

```auto
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?

---

<div class="post-metadata">

**Author:** ![talex5](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/talex5/32/353_2.png) [@talex5](https://discuss.ocaml.org/u/talex5)\
**Post date:** [September 5, 2024, 10:44am UTC](https://discuss.ocaml.org/t/using-angstrom-with-eio/15242/4 "2024-09-05T10:44:25Z")

</div>

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:

> <https://github.com/ocaml-multicore/eio/blob/0f6b65dea27c40b7afd0cfdfe874356070fcc59e/lib_eio/buf_read.mli#L209-L230>

---

<div class="post-metadata">

**Author:** ![enetsee](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/enetsee/32/1041_2.png) [@enetsee](https://discuss.ocaml.org/u/enetsee)\
**Post date:** [September 5, 2024, 11:27am UTC](https://discuss.ocaml.org/t/using-angstrom-with-eio/15242/5 "2024-09-05T11:27:36Z")

</div>

Ah ok! Thanks so much for your help!!
