Skip to content

Commit e355419

Browse files
committed
Add FromIterator implementations for Box<str>
These are analogous to impl FromIterator<A> for Box<[A]> (rust-lang#55843). Fixes rust-lang#65163. Signed-off-by: Anders Kaseorg <andersk@mit.edu>
1 parent ae5b641 commit e355419

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

src/liballoc/boxed.rs

+37
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,10 @@ use core::slice;
147147
use core::task::{Context, Poll};
148148

149149
use crate::alloc::{self, AllocRef, Global};
150+
use crate::borrow::Cow;
150151
use crate::raw_vec::RawVec;
151152
use crate::str::from_boxed_utf8_unchecked;
153+
use crate::string::String;
152154
use crate::vec::Vec;
153155

154156
/// A pointer type for heap allocation.
@@ -1045,6 +1047,41 @@ impl<A> FromIterator<A> for Box<[A]> {
10451047
}
10461048
}
10471049

1050+
#[stable(feature = "boxed_str_from_iter", since = "1.44.0")]
1051+
impl<'a> FromIterator<&'a char> for Box<str> {
1052+
fn from_iter<T: IntoIterator<Item = &'a char>>(iter: T) -> Self {
1053+
iter.into_iter().collect::<String>().into_boxed_str()
1054+
}
1055+
}
1056+
1057+
#[stable(feature = "boxed_str_from_iter", since = "1.44.0")]
1058+
impl<'a> FromIterator<&'a str> for Box<str> {
1059+
fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> Self {
1060+
iter.into_iter().collect::<String>().into_boxed_str()
1061+
}
1062+
}
1063+
1064+
#[stable(feature = "boxed_str_from_iter", since = "1.44.0")]
1065+
impl<'a> FromIterator<Cow<'a, str>> for Box<str> {
1066+
fn from_iter<T: IntoIterator<Item = Cow<'a, str>>>(iter: T) -> Self {
1067+
iter.into_iter().collect::<String>().into_boxed_str()
1068+
}
1069+
}
1070+
1071+
#[stable(feature = "boxed_str_from_iter", since = "1.44.0")]
1072+
impl FromIterator<String> for Box<str> {
1073+
fn from_iter<T: IntoIterator<Item = String>>(iter: T) -> Self {
1074+
iter.into_iter().collect::<String>().into_boxed_str()
1075+
}
1076+
}
1077+
1078+
#[stable(feature = "boxed_str_from_iter", since = "1.44.0")]
1079+
impl FromIterator<char> for Box<str> {
1080+
fn from_iter<T: IntoIterator<Item = char>>(iter: T) -> Self {
1081+
iter.into_iter().collect::<String>().into_boxed_str()
1082+
}
1083+
}
1084+
10481085
#[stable(feature = "box_slice_clone", since = "1.3.0")]
10491086
impl<T: Clone> Clone for Box<[T]> {
10501087
fn clone(&self) -> Self {

src/liballoc/tests.rs

+18
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ use core::i64;
88
use core::ops::Deref;
99
use core::result::Result::{Err, Ok};
1010

11+
use std::borrow::Cow;
1112
use std::boxed::Box;
13+
use std::string::String;
1214

1315
#[test]
1416
fn test_owned_clone() {
@@ -140,6 +142,22 @@ fn boxed_slice_from_iter() {
140142
assert_eq!(boxed[7], 7);
141143
}
142144

145+
#[test]
146+
fn boxed_str_from_iter() {
147+
let s = "Hello, world!";
148+
let chars: Box<[char]> = s.chars().collect();
149+
let boxed: Box<str> = chars.iter().collect();
150+
assert_eq!(&*boxed, s);
151+
let boxed: Box<str> = [s].iter().cloned().collect();
152+
assert_eq!(&*boxed, s);
153+
let boxed: Box<str> = [Cow::from(s)].iter().cloned().collect();
154+
assert_eq!(&*boxed, s);
155+
let boxed: Box<str> = [String::from(s)].iter().cloned().collect();
156+
assert_eq!(&*boxed, s);
157+
let boxed: Box<str> = s.chars().collect();
158+
assert_eq!(&*boxed, s);
159+
}
160+
143161
#[test]
144162
fn test_array_from_slice() {
145163
let v = vec![1, 2, 3];

0 commit comments

Comments
 (0)