From f85c4cd79f6dc5466ecf7f760efda455655b6995 Mon Sep 17 00:00:00 2001 From: Samuel Goad <53803593+ellipse12@users.noreply.github.com> Date: Fri, 9 Aug 2024 15:10:46 -0600 Subject: [PATCH] Update string_iterator.c3 to include extra convenience methods (#1327) Update string_iterator.c3 to include extra convenience methods Added peek: returns the next character without incrementing current Added has_next: checks if the iterator has another element Added get: gets the current element (the same one that was returned with the previous call to next). --- lib/std/core/string_iterator.c3 | 40 +++++++++++++++++++----- test/unit/stdlib/core/string_iterator.c3 | 35 +++++++++++++++++++++ 2 files changed, 68 insertions(+), 7 deletions(-) create mode 100644 test/unit/stdlib/core/string_iterator.c3 diff --git a/lib/std/core/string_iterator.c3 b/lib/std/core/string_iterator.c3 index 299e0fd4d..abd7aa4a3 100644 --- a/lib/std/core/string_iterator.c3 +++ b/lib/std/core/string_iterator.c3 @@ -13,11 +13,37 @@ fn void StringIterator.reset(&self) fn Char32! StringIterator.next(&self) { - usz len = self.utf8.len; - usz current = self.current; - if (current >= len) return IteratorResult.NO_MORE_ELEMENT?; - usz read = (len - current < 4 ? len - current : 4); - Char32 res = conv::utf8_to_char32(&self.utf8[current], &read)!; - self.current += read; - return res; + usz len = self.utf8.len; + usz current = self.current; + if (current >= len) return IteratorResult.NO_MORE_ELEMENT?; + usz read = (len - current < 4 ? len - current : 4); + Char32 res = conv::utf8_to_char32(&self.utf8[current], &read)!; + self.current += read; + return res; +} + +fn Char32! StringIterator.peek(&self) +{ + usz len = self.utf8.len; + usz current = self.current; + if (current >= len) return IteratorResult.NO_MORE_ELEMENT?; + usz read = (len - current < 4 ? len - current : 4); + Char32 res = conv::utf8_to_char32(&self.utf8[current], &read)!; + return res; +} + +fn bool StringIterator.has_next(&self) +{ + return self.current < self.utf8.len; +} + +fn Char32! StringIterator.get(&self) +{ + usz len = self.utf8.len; + usz current = self.current; + usz read = (len - current < 4 ? len - current : 4); + usz index = current > read ? current - read : 0; + if (index >= len) return IteratorResult.NO_MORE_ELEMENT?; + Char32 res = conv::utf8_to_char32(&self.utf8[index], &read)!; + return res; } diff --git a/test/unit/stdlib/core/string_iterator.c3 b/test/unit/stdlib/core/string_iterator.c3 new file mode 100644 index 000000000..4b9615d4d --- /dev/null +++ b/test/unit/stdlib/core/string_iterator.c3 @@ -0,0 +1,35 @@ +module std::core::test::string_iterator::tests @test; + +fn void test_at_start() +{ + String test = "abcd"; + StringIterator iterator = test.iterator(); + assert(iterator.get()! == 'a'); + assert(iterator.peek()! == 'a'); + iterator.next()!; + assert(iterator.next()! == 'b'); + assert(iterator.has_next()); +} + + +fn void test_general() +{ + String test = "åƦs1"; + StringIterator iterator = test.iterator(); + assert(iterator.get()! == 'å'); + iterator.next()!; + assert(iterator.peek()! == 'Ʀ'); + assert(iterator.next()! == 'Ʀ'); + iterator.reset(); + assert(iterator.current == 0); +} + +fn void test_end() +{ + String test = "åƦ"; + StringIterator iterator = test.iterator(); + assert(@ok(iterator.next())); + assert(iterator.peek()! == 'Ʀ'); + assert(@ok(iterator.next())); + assert(@catch(iterator.next())); +}