Skip to content

Commit 2370d89

Browse files
committed
Use byte slicing
1 parent 86712e6 commit 2370d89

File tree

2 files changed

+18
-7
lines changed

2 files changed

+18
-7
lines changed

src/gleam/string.gleam

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -196,17 +196,21 @@ pub fn slice(from string: String, at_index idx: Int, length len: Int) -> String
196196
let translated_idx = length(string) + idx
197197
case translated_idx < 0 {
198198
True -> ""
199-
False -> do_slice(string, translated_idx, len)
199+
False -> grapheme_slice(string, translated_idx, len)
200200
}
201201
}
202-
False -> do_slice(string, idx, len)
202+
False -> grapheme_slice(string, idx, len)
203203
}
204204
}
205205
}
206206

207207
@external(erlang, "gleam_stdlib", "slice")
208-
@external(javascript, "../gleam_stdlib.mjs", "string_slice")
209-
fn do_slice(string: String, idx: Int, len: Int) -> String
208+
@external(javascript, "../gleam_stdlib.mjs", "string_grapheme_slice")
209+
fn grapheme_slice(string: String, index: Int, length: Int) -> String
210+
211+
@external(erlang, "binary", "part")
212+
@external(javascript, "../gleam_stdlib.mjs", "string_byte_slice")
213+
fn unsafe_byte_slice(string: String, index: Int, length: Int) -> String
210214

211215
/// Drops contents of the first `String` that occur before the second `String`.
212216
/// If the `from` string does not contain the `before` string, `from` is
@@ -225,6 +229,8 @@ pub fn crop(from string: String, before substring: String) -> String
225229

226230
/// Drops *n* graphemes from the start of a `String`.
227231
///
232+
/// This function runs in linear time with the number of graphemes to drop.
233+
///
228234
/// ## Examples
229235
///
230236
/// ```gleam
@@ -236,8 +242,9 @@ pub fn drop_start(from string: String, up_to num_graphemes: Int) -> String {
236242
case num_graphemes <= 0 {
237243
True -> string
238244
False -> {
239-
let bigger_than_rest_of_string = byte_size(string) * 32
240-
slice(string, num_graphemes, bigger_than_rest_of_string)
245+
let prefix = grapheme_slice(string, 0, num_graphemes)
246+
let prefix_size = byte_size(prefix)
247+
unsafe_byte_slice(string, prefix_size, byte_size(string) - prefix_size)
241248
}
242249
}
243250
}

src/gleam_stdlib.mjs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,11 @@ export function length(data) {
193193
return data.length;
194194
}
195195

196-
export function string_slice(string, idx, len) {
196+
export function string_byte_slice(string, index, length) {
197+
return string.slice(index, index + length);
198+
}
199+
200+
export function string_grapheme_slice(string, idx, len) {
197201
if (len <= 0 || idx >= string.length) {
198202
return "";
199203
}

0 commit comments

Comments
 (0)