open Types type serialiser = { mutable buf : bytes; mutable pos : int } (* convert ansi variants to appropriate output codes *) let write_ansi a = let rec intersperse sep ls = match ls with | [] | [ _ ] -> ls | hd :: tl -> hd :: sep :: intersperse sep tl and string_of_colour ?(bg = false) c = let prefix = if bg then "4" else "3" and si = string_of_int in c |> function | Intrinsic i -> prefix ^ si i | Simple i -> prefix ^ "8;5;" ^ si i | RGB (r, g, b) -> prefix ^ "8;2;" ^ si r ^ ";" ^ si g ^ ";" ^ si b in let ansi = a |> List.map (fun a -> match a with | Fg c -> string_of_colour c | Bg c -> string_of_colour ~bg:true c | Reset -> "0" | Other i -> string_of_int i) |> intersperse ";" |> List.fold_left (fun acc el -> acc ^ el) "" in "\x1b[" ^ ansi ^ "m" (* print all serialised data and reset buffer *) let flush t = if t.pos > 0 then ( print_bytes (Bytes.sub t.buf 0 t.pos); t.pos <- 0) let serialise t chunk = let input = match chunk with | Text s -> s | Separator s -> s | Delimiter s -> s | Ansi a -> write_ansi a and sz = Bytes.length t.buf in let input_sz = String.length input in if t.pos + input_sz > sz then flush t; if input_sz > sz then print_string input else ( Bytes.blit_string input 0 t.buf t.pos input_sz; t.pos <- t.pos + input_sz) let create = { buf = Bytes.create 4096; pos = 0 }