Skip to content

Commit f0893bc

Browse files
committed
fix index_of and refactor
1 parent 669e73b commit f0893bc

File tree

2 files changed

+67
-19
lines changed

2 files changed

+67
-19
lines changed

string/string.mbt

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -351,22 +351,27 @@ pub fn is_blank(self : String) -> Bool {
351351
///|
352352
/// Returns the first index of the sub string.
353353
pub fn index_of(self : String, str : String, from~ : Int = 0) -> Int {
354-
let from = if from < 0 {
355-
0
356-
} else if from >= self.length() {
357-
self.length() - 1
358-
} else {
359-
from
360-
}
361354
let len = self.length()
362355
let sub_len = str.length()
363-
let max_idx = len - sub_len
356+
357+
// Handle empty substring case
364358
if sub_len == 0 {
365-
return 0
359+
// Return 0 for empty string in empty string
360+
if len == 0 {
361+
return 0
362+
}
363+
// Bound from within valid range and return it
364+
return if from < 0 { 0 } else if from >= len { len } else { from }
366365
}
366+
367+
// If substring is longer than string, it can't be found
367368
if sub_len > len {
368369
return -1
369370
}
371+
372+
// Bound the starting position
373+
let from = if from < 0 { 0 } else if from >= len { len - 1 } else { from }
374+
let max_idx = len - sub_len
370375
let first = str[0]
371376
let mut i = from
372377
while i <= max_idx {
@@ -376,14 +381,11 @@ pub fn index_of(self : String, str : String, from~ : Int = 0) -> Int {
376381
}
377382
// check the rest
378383
if i <= max_idx {
379-
let mut j = i + 1
380-
let mut k = 1
381-
let end = j + sub_len - 1
382-
while j < end && self[j] == str[k] {
383-
j += 1
384-
k += 1
385-
}
386-
if j == end {
384+
for j = 1; j < sub_len; j = j + 1 {
385+
if self[i + j] != str[j] {
386+
break
387+
}
388+
} else {
387389
return i
388390
}
389391
}

string/string_test.mbt

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,52 @@ test "index_of" {
287287
inspect!("abc".index_of("b", from=100), content="-1")
288288
}
289289

290+
///|
291+
test "String::index_of empty strings" {
292+
// Empty string cases
293+
assert_eq!("".index_of(""), 0)
294+
assert_eq!("abc".index_of(""), 0)
295+
assert_eq!("".index_of("a"), -1)
296+
}
297+
298+
///|
299+
test "String::index_of basic matching" {
300+
// Basic substring matching
301+
assert_eq!("abc".index_of("a"), 0)
302+
assert_eq!("abc".index_of("b"), 1)
303+
assert_eq!("abc".index_of("c"), 2)
304+
assert_eq!("abc".index_of("ab"), 0)
305+
assert_eq!("abc".index_of("bc"), 1)
306+
assert_eq!("abc".index_of("abc"), 0)
307+
assert_eq!("abc".index_of("d"), -1)
308+
assert_eq!("abc".index_of("abcd"), -1)
309+
}
310+
311+
///|
312+
test "String::index_of with from parameter" {
313+
// Testing from parameter
314+
assert_eq!("abcabc".index_of("a", from=1), 3)
315+
assert_eq!("abcabc".index_of("a", from=4), -1)
316+
assert_eq!("abcabc".index_of("bc", from=2), 4)
317+
assert_eq!("abc".index_of("", from=1), 1)
318+
assert_eq!("abc".index_of("", from=3), 3)
319+
assert_eq!("abc".index_of("", from=4), 3) // Bounded to length
320+
}
321+
322+
///|
323+
test "String::index_of with negative from" {
324+
// Testing negative from parameter
325+
assert_eq!("abc".index_of("a", from=-1), 0)
326+
assert_eq!("abc".index_of("b", from=-2), 1)
327+
}
328+
329+
///|
330+
test "String::index_of overlapping patterns" {
331+
// Testing overlapping patterns
332+
assert_eq!("aaa".index_of("aa"), 0)
333+
assert_eq!("aaa".index_of("aa", from=1), 1)
334+
}
335+
290336
///|
291337
test "last_index_of" {
292338
inspect!("abc".last_index_of("a"), content="0")
@@ -589,8 +635,8 @@ test "string pattern matching" {
589635
} derive(Show)
590636
fn process_string(s : String) {
591637
match s {
592-
[.."true", ..] => True
593-
[.."false", ..] => False
638+
[.. "true", ..] => True
639+
[.. "false", ..] => False
594640
_ => Other
595641
}
596642
}

0 commit comments

Comments
 (0)