let sequence_id_of_string s =
let open Result.Monad_infix in
let i name value =
try Ok (Int.of_string value)
with Failure _ ->
error (sprintf "%s not an int" name) value sexp_of_string
in
let b name value = match value with
| "Y" -> Ok true
| "N" -> Ok false
| _ -> error (sprintf "%s must be Y or N" name) value sexp_of_string
in
match String.lsplit2 s ~on:' ' with
| Some (x,y) -> (
match String.split x ~on:':', String.split y ~on:':' with
| [instrument;run_number;flowcell_id;lane;tile;x_pos;y_pos],
[read;is_filtered;control_number;index] ->
i "run_number" run_number >>= fun run_number ->
i "lane" lane >>= fun lane ->
tile_of_string tile >>= fun tile ->
i "x_pos" x_pos >>= fun x_pos ->
i "y_pos" y_pos >>= fun y_pos ->
i "read" read >>= fun read ->
b "is_filtered" is_filtered >>= fun is_filtered ->
i "control_number" control_number >>= fun control_number ->
Ok {instrument; run_number; flowcell_id; lane; tile; x_pos; y_pos;
read; is_filtered; control_number; index}
| _ -> error "invalid Illumina sequence identifier" s sexp_of_string
)
| _ -> error "invalid Illumina sequence identifier" s sexp_of_string