let parse_cigar_text text =
  let open Result.Monad_infix in
  if text = "*" then Ok [| |]
  else begin
    let ch = Scanf.Scanning.from_string text in
    let rec loop acc =
      if Scanf.Scanning.end_of_input ch then Ok acc
      else begin
        try
          let v = Scanf.bscanf ch "%d" ident in
          let c = Scanf.bscanf ch "%c" ident in
          match c with
          | 'M' -> (loop (`M  v :: acc))
          | 'I' -> (loop (`I  v :: acc))
          | 'D' -> (loop (`D  v :: acc))
          | 'N' -> (loop (`N  v :: acc))
          | 'S' -> (loop (`S  v :: acc))
          | 'H' -> (loop (`H  v :: acc))
          | 'P' -> (loop (`P  v :: acc))
          | '=' -> (loop (`Eq v :: acc))
          | 'X' -> (loop (`X  v :: acc))
          | other -> failwith ""
        with
          e -> Error (`wrong_cigar_text text)
      end
    in
    loop [] >>| Array.of_list_rev
  end