diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index 8240aafae74e..8bdd9a88473f 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -1204,6 +1204,16 @@ impl<'a> Extend<&'a OsStr> for OsString { } } +#[stable(feature = "osstring_extend", since = "1.52.0")] +impl<'a> Extend> for OsString { + #[inline] + fn extend>>(&mut self, iter: T) { + for s in iter { + self.push(&s); + } + } +} + #[stable(feature = "osstring_extend", since = "1.52.0")] impl FromIterator for OsString { #[inline] @@ -1234,3 +1244,27 @@ impl<'a> FromIterator<&'a OsStr> for OsString { buf } } + +#[stable(feature = "osstring_extend", since = "1.52.0")] +impl<'a> FromIterator> for OsString { + #[inline] + fn from_iter>>(iter: I) -> Self { + let mut iterator = iter.into_iter(); + + // Because we're iterating over `OsString`s, we can avoid at least + // one allocation by getting the first owned string from the iterator + // and appending to it all the subsequent strings. + match iterator.next() { + None => OsString::new(), + Some(Cow::Owned(mut buf)) => { + buf.extend(iterator); + buf + } + Some(Cow::Borrowed(buf)) => { + let mut buf = OsString::from(buf); + buf.extend(iterator); + buf + } + } + } +}