Declarative CSV codecs
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

csvt: rename get_col → col, fix docs, shorten test name (merlint)

+17 -17
+2 -2
fuzz/fuzz_csvt.ml
··· 55 55 56 56 (* {1 Crash safety: arbitrary bytes never cause a crash} *) 57 57 58 - let test_no_crash_on_arbitrary_input bytes = 58 + let test_no_crash_arbitrary bytes = 59 59 (* Decoding arbitrary bytes should either succeed or return Error, 60 60 never crash *) 61 61 ignore (Csvt.decode_string int_codec bytes); ··· 222 222 ( "csvt", 223 223 [ 224 224 test_case "no crash on arbitrary" [ bytes ] 225 - test_no_crash_on_arbitrary_input; 225 + test_no_crash_arbitrary; 226 226 test_case "int roundtrip" [ int ] test_int_roundtrip; 227 227 test_case "float roundtrip" [ float ] test_float_roundtrip; 228 228 test_case "bool roundtrip" [ bool ] test_bool_roundtrip;
+6 -6
lib/csvt.ml
··· 272 272 273 273 The paper's [mem] combinator, adapted for CSV. *) 274 274 275 - let get_col name t = Row.(obj Fun.id |> col name t ~enc:Fun.id |> finish) 275 + let col name t = Row.(obj Fun.id |> col name t ~enc:Fun.id |> finish) 276 276 277 277 (* {1 Update support} *) 278 278 279 - let find_col_by_name header name = 279 + let col_by_name header name = 280 280 let name = String.trim name in 281 281 let n = Array.length header in 282 282 let rec go i = ··· 287 287 go 0 288 288 289 289 let update_col name codec f header row = 290 - let idx = find_col_by_name header name in 290 + let idx = col_by_name header name in 291 291 if idx < 0 then Error (Missing_column name) 292 292 else if idx >= Array.length row then 293 293 Error ··· 303 303 Ok result 304 304 305 305 let delete_col name header row = 306 - let idx = find_col_by_name header name in 306 + let idx = col_by_name header name in 307 307 if idx < 0 then (header, row) 308 308 else 309 309 let n = Array.length header in ··· 330 330 r_dec : ('a, 'a) dec_fun; 331 331 } 332 332 333 - let find_col header name = 333 + let resolve_col header name = 334 334 let name = String.trim name in 335 335 let n = Array.length header in 336 336 let rec go i = ··· 349 349 if i >= n then Ok { r_indices = indices; r_mems = mems; r_dec = m.dec } 350 350 else 351 351 let (Mem_dec mm) = mems.(i) in 352 - let idx = find_col header mm.name in 352 + let idx = resolve_col header mm.name in 353 353 indices.(i) <- idx; 354 354 if idx < 0 && Option.is_none mm.dec_absent then 355 355 Error (Missing_column mm.name)
+4 -4
lib/csvt.mli
··· 77 77 [false]. *) 78 78 79 79 val nullable_float : float t 80 - (** Like {!float} but treats ["NULL"] and empty strings as [nan]. *) 80 + (** [nullable_float] is like {!float} but treats ["NULL"] and empty strings as [nan]. *) 81 81 82 82 val nullable_int : int t 83 - (** Like {!int} but treats ["NULL"] and empty strings as [-1]. *) 83 + (** [nullable_int] is like {!int} but treats ["NULL"] and empty strings as [-1]. *) 84 84 85 85 val option : 'a t -> 'a option t 86 86 (** [option t] treats ["NULL"] and empty strings as [None], otherwise decodes ··· 104 104 105 105 (** {1:query Query} *) 106 106 107 - val get_col : string -> 'a t -> 'a t 108 - (** [get_col name t] creates a single-column row codec that extracts column 107 + val col : string -> 'a t -> 'a t 108 + (** [col name t] creates a single-column row codec that extracts column 109 109 [name] decoded with [t]. Useful for projecting a single column from a CSV 110 110 file without defining a full row type. *) 111 111
+5 -5
test/test_csvt.ml
··· 646 646 647 647 let test_get_col_int () = 648 648 let csv = "id,name,score,active\n1,alice,95.5,true\n2,bob,87.3,false\n" in 649 - let id_codec = Csvt.get_col "id" Csvt.int in 649 + let id_codec = Csvt.col "id" Csvt.int in 650 650 match Csvt.decode_string id_codec csv with 651 651 | Error e -> Alcotest.failf "get_col id: %s" (Csvt.error_to_string e) 652 652 | Ok ids -> Alcotest.(check (list int)) "ids" [ 1; 2 ] ids 653 653 654 654 let test_get_col_string () = 655 655 let csv = "id,name,score,active\n1,alice,95.5,true\n2,bob,87.3,false\n" in 656 - let name_codec = Csvt.get_col "name" Csvt.string in 656 + let name_codec = Csvt.col "name" Csvt.string in 657 657 match Csvt.decode_string name_codec csv with 658 658 | Error e -> Alcotest.failf "get_col name: %s" (Csvt.error_to_string e) 659 659 | Ok names -> Alcotest.(check (list string)) "names" [ "alice"; "bob" ] names 660 660 661 661 let test_get_col_missing () = 662 662 let csv = "id,name\n1,alice\n" in 663 - let score_codec = Csvt.get_col "score" Csvt.float in 663 + let score_codec = Csvt.col "score" Csvt.float in 664 664 match Csvt.decode_string score_codec csv with 665 665 | Ok _ -> Alcotest.fail "expected error for missing column" 666 666 | Error (Csvt.Missing_column "score") -> () 667 667 | Error e -> Alcotest.failf "unexpected error: %s" (Csvt.error_to_string e) 668 668 669 669 let test_get_col_encode () = 670 - let codec = Csvt.get_col "v" Csvt.int in 670 + let codec = Csvt.col "v" Csvt.int in 671 671 let h = Csvt.Private.encode_header codec in 672 672 Alcotest.(check (array string)) "header" [| "v" |] h; 673 673 let row = Csvt.Private.encode_row codec 42 in 674 674 Alcotest.(check (array string)) "row" [| "42" |] row 675 675 676 676 let test_get_col_col_names () = 677 - let codec = Csvt.get_col "score" Csvt.float in 677 + let codec = Csvt.col "score" Csvt.float in 678 678 Alcotest.(check (list string)) "col_names" [ "score" ] (Csvt.col_names codec); 679 679 Alcotest.(check int) "col_count" 1 (Csvt.col_count codec) 680 680