Skip to content

Commit 2fde772

Browse files
committed
Reitroduce Stringlike trait and use it for Stringlike.find()
Signed-off-by: martinvuyk <[email protected]>
1 parent 5655490 commit 2fde772

File tree

3 files changed

+69
-16
lines changed

3 files changed

+69
-16
lines changed

stdlib/src/builtin/string_literal.mojo

+10-4
Original file line numberDiff line numberDiff line change
@@ -591,31 +591,37 @@ struct StringLiteral(
591591

592592
writer.write(self.as_string_slice())
593593

594-
fn find(self, substr: StringLiteral, start: Int = 0) -> Int:
594+
fn find[T: Stringlike, //](self, substr: T, start: Int = 0) -> Int:
595595
"""Finds the offset of the first occurrence of `substr` starting at
596596
`start`. If not found, returns -1.
597597
598+
Parameters:
599+
T: The Stringlike type.
600+
598601
Args:
599602
substr: The substring to find.
600603
start: The offset from which to find.
601604
602605
Returns:
603606
The offset of `substr` relative to the beginning of the string.
604607
"""
605-
return StringRef(self).find(substr, start=start)
608+
return self.as_string_slice().find(substr, start=start)
606609

607-
fn rfind(self, substr: StringLiteral, start: Int = 0) -> Int:
610+
fn rfind[T: Stringlike, //](self, substr: T, start: Int = 0) -> Int:
608611
"""Finds the offset of the last occurrence of `substr` starting at
609612
`start`. If not found, returns -1.
610613
614+
Parameters:
615+
T: The Stringlike type.
616+
611617
Args:
612618
substr: The substring to find.
613619
start: The offset from which to find.
614620
615621
Returns:
616622
The offset of `substr` relative to the beginning of the string.
617623
"""
618-
return StringRef(self).rfind(substr, start=start)
624+
return self.as_string_slice().rfind(substr, start=start)
619625

620626
fn replace(self, old: StringLiteral, new: StringLiteral) -> StringLiteral:
621627
"""Return a copy of the string with all occurrences of substring `old`

stdlib/src/collections/string.mojo

+10-8
Original file line numberDiff line numberDiff line change
@@ -1707,35 +1707,37 @@ struct String(
17071707
"""
17081708
return substr.as_string_slice() in self.as_string_slice()
17091709

1710-
fn find(self, substr: String, start: Int = 0) -> Int:
1710+
fn find[T: Stringlike, //](self, substr: T, start: Int = 0) -> Int:
17111711
"""Finds the offset of the first occurrence of `substr` starting at
17121712
`start`. If not found, returns -1.
17131713
1714+
Parameters:
1715+
T: The Stringlike type.
1716+
17141717
Args:
17151718
substr: The substring to find.
17161719
start: The offset from which to find.
17171720
17181721
Returns:
17191722
The offset of `substr` relative to the beginning of the string.
17201723
"""
1724+
return self.as_string_slice().find(substr, start)
17211725

1722-
return self.as_string_slice().find(substr.as_string_slice(), start)
1723-
1724-
fn rfind(self, substr: String, start: Int = 0) -> Int:
1726+
fn rfind[T: Stringlike, //](self, substr: T, start: Int = 0) -> Int:
17251727
"""Finds the offset of the last occurrence of `substr` starting at
17261728
`start`. If not found, returns -1.
17271729
1730+
Parameters:
1731+
The Stringlike type.
1732+
17281733
Args:
17291734
substr: The substring to find.
17301735
start: The offset from which to find.
17311736
17321737
Returns:
17331738
The offset of `substr` relative to the beginning of the string.
17341739
"""
1735-
1736-
return self.as_string_slice().rfind(
1737-
substr.as_string_slice(), start=start
1738-
)
1740+
return self.as_string_slice().rfind(substr, start=start)
17391741

17401742
fn isspace(self) -> Bool:
17411743
"""Determines whether every character in the given String is a

stdlib/src/utils/string_slice.mojo

+49-4
Original file line numberDiff line numberDiff line change
@@ -885,10 +885,14 @@ struct StringSlice[is_mutable: Bool, //, origin: Origin[is_mutable]](
885885
"""
886886
return _FormatCurlyEntry.format(self, args)
887887

888-
fn find(ref self, substr: StringSlice, start: Int = 0) -> Int:
888+
# FIXME(#3526): this should return unicode codepoint offsets
889+
fn find[T: Stringlike, //](ref self, substr: T, start: Int = 0) -> Int:
889890
"""Finds the offset of the first occurrence of `substr` starting at
890891
`start`. If not found, returns `-1`.
891892
893+
Parameters:
894+
T: The Stringlike type.
895+
892896
Args:
893897
substr: The substring to find.
894898
start: The offset from which to find.
@@ -918,10 +922,14 @@ struct StringSlice[is_mutable: Bool, //, origin: Origin[is_mutable]](
918922

919923
return int(loc) - int(self.unsafe_ptr())
920924

921-
fn rfind(self, substr: StringSlice, start: Int = 0) -> Int:
925+
# FIXME(#3526): this should return unicode codepoint offsets
926+
fn rfind[T: Stringlike, //](self, substr: T, start: Int = 0) -> Int:
922927
"""Finds the offset of the last occurrence of `substr` starting at
923928
`start`. If not found, returns `-1`.
924929
930+
Parameters:
931+
T: The Stringlike type.
932+
925933
Args:
926934
substr: The substring to find.
927935
start: The offset from which to find.
@@ -930,9 +938,9 @@ struct StringSlice[is_mutable: Bool, //, origin: Origin[is_mutable]](
930938
The offset of `substr` relative to the beginning of the string.
931939
"""
932940
if not substr:
933-
return len(self)
941+
return self.byte_length()
934942

935-
if len(self) < len(substr) + start:
943+
if self.byte_length() < substr.byte_length() + start:
936944
return -1
937945

938946
# The substring to search within, offset from the beginning if `start`
@@ -1091,6 +1099,43 @@ struct StringSlice[is_mutable: Bool, //, origin: Origin[is_mutable]](
10911099
# ===-----------------------------------------------------------------------===#
10921100

10931101

1102+
trait Stringlike(CollectionElement, CollectionElementNew):
1103+
"""Trait intended to be used as a generic entrypoint for all String-like
1104+
types."""
1105+
1106+
fn byte_length(self) -> Int:
1107+
"""Get the string length in bytes.
1108+
Returns:
1109+
The length of this string in bytes.
1110+
Notes:
1111+
This does not include the trailing null terminator in the count.
1112+
"""
1113+
...
1114+
1115+
fn unsafe_ptr(self) -> UnsafePointer[Byte]:
1116+
"""Get raw pointer to the underlying data.
1117+
Returns:
1118+
The raw pointer to the data.
1119+
"""
1120+
...
1121+
1122+
fn find[T: Stringlike, //](self, substr: T, start: Int = 0) -> Int:
1123+
"""Finds the offset of the first occurrence of `substr` starting at
1124+
`start`. If not found, returns -1.
1125+
1126+
Parameters:
1127+
T: The type of the substring.
1128+
1129+
Args:
1130+
substr: The substring to find.
1131+
start: The offset from which to find.
1132+
1133+
Returns:
1134+
The offset of `substr` relative to the beginning of the string.
1135+
"""
1136+
...
1137+
1138+
10941139
fn _to_string_list[
10951140
T: CollectionElement, # TODO(MOCO-1446): Make `T` parameter inferred
10961141
len_fn: fn (T) -> Int,

0 commit comments

Comments
 (0)