let parse_header_line position line =
  match String.(split ~on:'\t' (chop_prefix_exn line ~prefix:"@")) with
  | [] -> assert false
  | "CO" :: rest -> return (`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 return (tag_values ()) with
      | Failure _ -> fail (`invalid_tag_value_list (position, values))
      end
      >>= fun tv ->
      return (`header (tag, tv))
    ) else
      fail (`invalid_header_tag (position, tag))