Skip to content

Commit dc4deae

Browse files
committed
add from iterator impl
1 parent 812c83a commit dc4deae

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

src/array_string.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,36 @@ impl<const CAP: usize> ArrayString<CAP>
295295
Ok(())
296296
}
297297

298+
pub fn try_push_iterator<I: IntoIterator<Item = char>>(&mut self, value: I) -> Result<(), CapacityError<()>> {
299+
let mut len = self.len();
300+
let value = value.into_iter();
301+
if value.size_hint().0 > self.capacity() - len {
302+
return Err(CapacityError::new(()));
303+
}
304+
305+
unsafe {
306+
let mut ptr = self.as_mut_ptr().add(self.len());
307+
for c in value {
308+
let remaining_cap = self.capacity() - len;
309+
match encode_utf8(c, ptr, remaining_cap) {
310+
Ok(n) => {
311+
len += n;
312+
ptr = ptr.add(n);
313+
}
314+
Err(_) => return Err(CapacityError::new(())),
315+
}
316+
}
317+
self.set_len(len);
318+
Ok(())
319+
}
320+
}
321+
322+
pub fn try_from_iterator<I: IntoIterator<Item = char>>(value: I) -> Result<Self, CapacityError<()>> {
323+
let mut string = Self::new();
324+
string.try_push_iterator(value)?;
325+
Ok(string)
326+
}
327+
298328
/// Removes the last character from the string and returns it.
299329
///
300330
/// Returns `None` if this `ArrayString` is empty.

tests/tests.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -774,3 +774,28 @@ fn test_arraystring_zero_filled_has_some_sanity_checks() {
774774
assert_eq!(string.as_str(), "\0\0\0\0");
775775
assert_eq!(string.len(), 4);
776776
}
777+
778+
#[test]
779+
fn test_string_collect() {
780+
let text = "hello world";
781+
let u = ArrayString::<11>::try_from_iterator(text.chars()).unwrap();
782+
assert_eq!(u.as_str(), text);
783+
assert_eq!(u.len(), text.len());
784+
}
785+
786+
#[test]
787+
fn test_string_collect_seveal_times() {
788+
let text = "hello world";
789+
let mut u = ArrayString::<22>::try_from_iterator(text.chars()).unwrap();
790+
u.try_push_iterator(text.chars()).unwrap();
791+
assert_eq!(u.as_str(), &format!("{}{}", text, text));
792+
assert_eq!(u.len(), text.len()*2);
793+
}
794+
795+
796+
#[test]
797+
fn test_string_collect_error_on_overflow() {
798+
let text = "hello world";
799+
ArrayString::<10>::try_from_iterator(text.chars()).unwrap_err();
800+
}
801+

0 commit comments

Comments
 (0)