aboutsummaryrefslogtreecommitdiff
path: root/lib/csv/csv.ml
blob: db7329dfbeb3cf0a537d1732ce71679df135bf7a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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