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))