let mix ta tb =
let a_buffer = ref None in
let name =
sprintf "(mix <%s> <%s>)"
Option.(value ~default:"" (name ta))
Option.(value ~default:"" (name tb)) in
make_general ~name ()
~feed:(fun (a, b) -> feed ta a; feed tb b)
~stop:(fun () -> stop ta; stop tb)
~next:(fun () ->
begin match !a_buffer with
| None ->
begin match next ta with
| `output oa ->
begin match next tb with
| `output ob -> `output (`both (oa, ob))
| `not_ready -> a_buffer := Some oa; `not_ready
| `end_of_stream -> `end_of_stream
end
| `not_ready -> `not_ready
| `end_of_stream ->
begin match next tb with
| `output ob -> `output (`right ob)
| `not_ready -> `not_ready
| `end_of_stream -> `end_of_stream
end
end
| Some oa ->
begin match next tb with
| `output ob -> a_buffer := None; `output (`both (oa, ob))
| `not_ready -> `not_ready
| `end_of_stream -> a_buffer := None; `output (`left oa)
end
end)