let parse_header_line position line =
let open Result.Monad_infix in
match String.(split ~on:'\t' (chop_prefix_exn line ~prefix:"@")) with
| [] -> assert false
| "CO" :: rest -> Ok (`comment (String.concat ~sep:"\t" rest))
| tag :: values ->
if is_valid_tag tag then (
let tag_values () =
List.map values (fun v ->
match String.split ~on:':' v with
| tag :: value :: [] ->
if is_valid_tag tag then (tag, value)
else failwith "A"
| other -> failwith "A") in
begin try Ok (tag_values ()) with
| Failure _ -> Error (`invalid_tag_value_list (position, values))
end
>>= fun tv ->
Ok (`header (tag, tv))
) else
Error (`invalid_header_tag (position, tag))