blob: 36db97d5d75480d63b70c8614d37945cb7a73b9d (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
module Error = struct
open Concepts.Condition
let not_a_cursor () =
condition "not-a-cursor" "A handle was expected to carry the cursor protocol and did not" empty
end
type batch = {tuples: Concepts.Tuple.t BatFingerTree.t; exhausted: bool}
class type implementation = object
method fetch : int -> (batch, Concepts.Condition.condition) result
end
type Handle.protocol += Cursor of implementation
type t = implementation
let make impl = Cursor (impl :> implementation)
let from handle = Handle.into handle (function Cursor impl -> Some impl | _ -> None)
let require handle = from handle |> Option.to_result ~none:(Error.not_a_cursor ())
let fetch i limit = Handle.invoke i (fun o -> o#fetch limit)
let rec next i =
let open Utilities.Result in
let* batch = fetch i 1 in
match BatFingerTree.front batch.tuples with
| Some (_, tuple) -> Ok (Some tuple)
| None -> if batch.exhausted then Ok None else next i
let drain i ?(limit = 256) () =
let open Utilities.Result in
let rec loop tuples =
let* batch = fetch i limit in
let tuples = BatFingerTree.append tuples batch.tuples in
if batch.exhausted then Ok tuples else loop tuples
in
loop BatFingerTree.empty
|