let of_line ?(separators=[' '; '\t']) ?(strict_row_length=false)
?(strict_cell_type=false) ?format line =
let l = (line : Line.t :> string) in
let module With_exns = struct
exception Int_of_string of string
exception Float_of_string of string
let int s =
try Int.of_string s with e -> raise (Int_of_string s)
let float s =
try Float.of_string s with e -> raise (Float_of_string s)
let of_line ~format l =
let tokens =
String.split_on_chars ~on:separators l |> List.filter ~f:((<>) "")
|> Array.of_list in
begin match format with
| None ->
Ok (Array.map tokens ~f:(fun s -> `string s))
| Some format ->
begin try
if strict_row_length && Array.length format > Array.length tokens
then Error (`wrong_format (`column_number, format, l))
else begin
let row =
Array.mapi tokens ~f:(fun i tok ->
let typ =
if strict_cell_type then format.(i)
else (try format.(i) with _ -> `type_string) in
match typ with
| `type_int -> `int (int tok)
| `type_float -> `float (float tok)
| `type_string -> `string tok) in
Ok row
end
with
| Invalid_argument _ ->
Error (`wrong_format (`column_number, format, l))
| Int_of_string s ->
Error (`wrong_format (`int_of_string s, format, l))
| Float_of_string s ->
Error (`wrong_format (`float_of_string s, format, l))
end
end
end in
(With_exns.of_line ~format l : (t, _) Result.t)