diff options
Diffstat (limited to 'src/Lib/CSV.ml')
-rw-r--r-- | src/Lib/CSV.ml | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/src/Lib/CSV.ml b/src/Lib/CSV.ml new file mode 100644 index 0000000..f0366f7 --- /dev/null +++ b/src/Lib/CSV.ml @@ -0,0 +1,76 @@ +let to_string lines = + let + cell_to_string cell = + if Js.String.includes "\"" cell then + "\"" ^ (Js.String.replaceByRe [%re "/\"/g"] "\"\"" cell) ^ "\"" + else + cell + in let + line_to_string line = + line + |> Js.Array.map cell_to_string + |> Js.Array.joinWith "," + in lines + |> Js.Array.map line_to_string + |> Js.Array.joinWith "\n" + +let parse str = + let lines = [| |] in + let current_line = ref [| |] in + let current_cell = ref "" in + let in_quote = ref false in + let i = ref 0 in + let l = Js.String.length str in + let () = while !i < l do + let cc = Js.String.get str !i in + let nc = Js.String.get str (!i + 1) in + let () = + if !in_quote && cc == "\"" && nc == "\"" then + let () = current_cell := !current_cell ^ cc in + i := !i + 1 + else if cc == "\"" then + in_quote := not !in_quote + else if not !in_quote && cc == "," then + let _ = Js.Array.push !current_cell !current_line in + current_cell := "" + else if not !in_quote && ((cc == "\r" && nc == "\n") || cc == "\n" || cc == "\r") then + let _ = Js.Array.push !current_cell !current_line in + let _ = Js.Array.push !current_line lines in + let _ = current_line := [| |] in + current_cell := "" + else + current_cell := !current_cell ^ cc + in + i := !i + 1 + done + in + let _ = + if Js.String.length !current_cell > 0 then + let _ = Js.Array.push !current_cell !current_line in () + else + () + in + let _ = + if Js.Array.length !current_line > 0 then + let _ = Js.Array.push !current_line lines in () + else + () + in + lines + +let to_dicts lines = + let res = [| |] in + let () = + if Js.Array.length lines > 0 then + let header = Js.Array.unsafe_get lines 0 in + for i = 1 to Js.Array.length lines - 1 do + let line = Js.Array.unsafe_get lines i in + let dict = Js.Dict.empty() in + let () = + Js.Array.forEachi + (fun key j -> Js.Dict.set dict key (Js.Array.unsafe_get line j)) + header + in + ignore (Js.Array.push dict res) + done + in res |