let of_yojson j =
let open Pvem.Result in
let error ?json fmt =
ksprintf (fun s ->
fail (sprintf "%s%s" s
(Option.value_map ~default:"" json
~f:(fun j ->
sprintf " but got %s" @@
Yojson.Safe.pretty_to_string ~std:true j)))
) fmt in
let data_of_yojson =
function
| `Assoc ["paired-end", `Assoc ["r1", `String r1; "r2", `String r2]] ->
return (PE (r1, r2))
| `Assoc ["single-end", `String file] -> SE file |> return
| `Assoc ["bam", `Assoc ["kind", `String kind;
"sorting", sorting;
"reference-genome", `String refb;
"path", `String path;]] ->
begin match sorting with
| `Null -> return None
| `String "coordinate" -> Some `Coordinate |> return
| `String "read-name" -> Some `Read_name |> return
| other ->
error ~json:other "Expecting %S, %S or null (in \"sorting\": ...)"
"coordinate" "read-name"
end
>>= fun sorting ->
begin match kind with
| "single-end" -> return `SE
| "paired-end" -> return `PE
| other -> error "Kind in bam must be \"SE\" or \"PE\""
end
>>= fun kind ->
return (Of_bam (kind, sorting, refb, path))
| other ->
error ~json:other "Expecting string or null (in \"fragment\": ...)"
in
let fragment_of_yojson =
function
| `Assoc ["fragment-id", frag; "data", data] ->
begin match frag with
| `String s -> return (Some s)
| `Null -> return (None)
| other ->
error ~json:other "Expecting string or null (in \"fragment\": ...)"
end
>>= fun fragment_id ->
data_of_yojson data
>>= fun data_parsed ->
return (fragment_id, data_parsed)
| other -> error ~json:other "Expecting {\"fragment\": ... , \"data\": ...}"
in
match j with
| `Assoc [vtag, more] when vtag = current_version_tag ->
begin match more with
| `Assoc ["fastq",
`Assoc ["sample-name", `String sample; "fragments", `List frgs]] ->
List.fold ~init:(return []) frgs ~f:(fun prev frag ->
prev >>= fun p ->
fragment_of_yojson frag
>>= fun more ->
return (more :: p))
>>= fun l ->
return (Fastq { fastq_sample_name = sample; files = List.rev l })
| `Assoc ["bam", bam] ->
begin match bam_of_yojson bam with
| Result.Ok ok -> return ok
| Result.Error err -> fail err
end
>>= fun bam ->
return (Bam bam)
| other ->
error ~json:other "Expecting Fastq or Bam"
end
| other ->
error ~json:other "Expecting Biokepi_input_v0"