aboutsummaryrefslogtreecommitdiff
path: root/lib/csv/csv.ml
diff options
context:
space:
mode:
Diffstat (limited to 'lib/csv/csv.ml')
-rw-r--r--lib/csv/csv.ml30
1 files changed, 30 insertions, 0 deletions
diff --git a/lib/csv/csv.ml b/lib/csv/csv.ml
new file mode 100644
index 0000000..db7329d
--- /dev/null
+++ b/lib/csv/csv.ml
@@ -0,0 +1,30 @@
+open StdLabels
+
+type t = int
+
+let column_of_char = function
+ | 'A' .. 'Z' as c -> Char.code c - (Char.code 'A' - 1)
+ | 'a' .. 'z' as c -> Char.code c - (Char.code 'a' - 1)
+ | c -> raise (Invalid_argument ("column: " ^ Char.escaped c))
+
+let column_of_string : string -> int =
+ fun s ->
+ String.fold_left s ~init:0 ~f:(fun value c -> (value * 26) + column_of_char c)
+
+(** Accumulate the remaining for the successives divisions in a list. *)
+let rec _to_char ~b i =
+ if i > 0 then
+ let res = i mod 26 in
+ let res = if res = 0 then 26 else res in
+
+ let c = char_of_int @@ (res + 64) in
+ (* The modulo is accumulated in the list head, which is the expected
+ sequence *)
+ let b = c :: b in
+
+ _to_char ~b @@ ((i - res) / 26)
+ else b
+
+let column_to_string i =
+ let res = _to_char ~b:[] i in
+ List.to_seq res |> String.of_seq