Skip to content

Commit

Permalink
Add native code to Js.String.split (#168)
Browse files Browse the repository at this point in the history
  • Loading branch information
pedrobslisboa authored Aug 27, 2024
1 parent 26affb8 commit fa5e286
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 14 deletions.
14 changes: 13 additions & 1 deletion packages/melange.js/Js.ml
Original file line number Diff line number Diff line change
Expand Up @@ -757,7 +757,19 @@ end = struct
if start_idx >= end_idx then ""
else Stdlib.String.sub str start_idx (end_idx - start_idx)

let split ?sep ?limit _str = notImplemented "Js.String" "split"
let split ?sep ?limit str =
let sep = Option.value sep ~default:str in
let regexp = Str.regexp_string sep in
(* On js split, it don't return an empty string on end when separator is an empty string *)
(* but "split_delim" does *)
(* https://melange.re/unstable/playground/?language=OCaml&code=SnMubG9nKEpzLlN0cmluZy5zcGxpdCB%2Bc2VwOiIiICJzdGFydCIpOw%3D%3D&live=off *)
let split = if sep <> "" then Str.split_delim else Str.split in
let items = split regexp str |> Stdlib.Array.of_list in
let limit = Option.value limit ~default:(Stdlib.Array.length items) in
match limit with
| limit when limit >= 0 && limit < Stdlib.Array.length items ->
Stdlib.Array.sub items 0 limit
| _ -> items

let splitByRe ~regexp ?limit str =
let rev_array arr =
Expand Down
4 changes: 0 additions & 4 deletions packages/melange.js/Js.mli
Original file line number Diff line number Diff line change
Expand Up @@ -380,11 +380,7 @@ module String : sig
not_implemented "is not implemented in native under server-reason-react.js"]

val slice : ?start:int -> ?end_:int -> t -> t

val split : ?sep:t -> ?limit:int -> t -> t array
[@@alert
not_implemented "is not implemented in native under server-reason-react.js"]

val splitByRe : regexp:Re.t -> ?limit:int -> t -> t nullable array
val startsWith : prefix:t -> ?start:int -> t -> bool
val substr : ?start:int -> ?len:int -> t -> t
Expand Down
48 changes: 39 additions & 9 deletions packages/melange.js/test.ml
Original file line number Diff line number Diff line change
Expand Up @@ -302,15 +302,45 @@ let string_tests =
(* assert_string (Js.String.sliceToEnd ~from:(-2) "abcdefg") "fg"; *)
assert_string (Js.String.slice ~start:7 "abcdefg") "");
test "split" (fun () ->
(* assert_string_array (split "-" "2018-01-02") [| "2018"; "01"; "02" |];
assert_string_array (split "," "a,b,,c") [| "a"; "b"; ""; "c" |];
assert_string_array
(split "::" "good::bad as great::awful")
[| "good"; "bad as great"; "awful" |];
assert_string_array
(split ";" "has-no-delimiter")
[| "has-no-delimiter" |] *)
());
assert_string_array (Js.String.split ~sep:"" "") [||];
assert_string_array
(Js.String.split ~sep:"-" "2018-01-02")
[| "2018"; "01"; "02" |];
assert_string_array
(Js.String.split ~sep:"," "a,b,,c")
[| "a"; "b"; ""; "c" |];
assert_string_array
(Js.String.split ~sep:"::" "good::bad as great::awful")
[| "good"; "bad as great"; "awful" |];
assert_string_array
(Js.String.split ~sep:";" "has-no-delimiter")
[| "has-no-delimiter" |];
assert_string_array
(Js.String.split ~sep:"with" "with-sep-equals-to-beginning")
[| ""; "-sep-equals-to-beginning" |];
assert_string_array
(Js.String.split ~sep:"end" "with-sep-equals-to-end")
[| "with-sep-equals-to-"; "" |];
assert_string_array
(Js.String.split ~sep:"/" "/with-sep-on-beginning-and-end/")
[| ""; "with-sep-on-beginning-and-end"; "" |];
assert_string_array
(Js.String.split ~sep:"" "with-empty-sep")
[|
"w"; "i"; "t"; "h"; "-"; "e"; "m"; "p"; "t"; "y"; "-"; "s"; "e"; "p";
|];
assert_string_array
(Js.String.split ~sep:"-" "with-limit-equals-to-zero" ~limit:0)
[||];
assert_string_array
(Js.String.split ~sep:"-" "with-limit-equals-to-length" ~limit:5)
[| "with"; "limit"; "equals"; "to"; "length" |];
assert_string_array
(Js.String.split ~sep:"-" "with-limit-greater-than-length" ~limit:100)
[| "with"; "limit"; "greater"; "than"; "length" |];
assert_string_array
(Js.String.split ~sep:"-" "with-limit-less-than-zero" ~limit:(-2))
[| "with"; "limit"; "less"; "than"; "zero" |]);
test "splitAtMost" (fun () ->
(* assert_string_array
(splitAtMost "/" ~limit:3 "ant/bee/cat/dog/elk")
Expand Down

0 comments on commit fa5e286

Please sign in to comment.