Skip to content

ACP: Implement FromIterator for Box<str> #196

Closed

Description

Proposal

Problem statement

Boxed slices are space-saving alternatives to Vec and String when the ability to grow the allocation is not required. To make them easier replacements, it would be ideal for Box<[T]> and Box<str> to provide all the functionality of Vec<T> and String that doesn't require resizing.
One functionality gap is that String implements FromIterator (for 6 types of Iterator item), but Box<str> doesn't. There's already an analogous implementation for Box<[T]>: FromIterator is implemented for Box<[T]> by using Vec<T>'s FromIterator implementation and then calling into_boxed_slice() to convert to a Box<[T]>. The proposal is to do the same thing for Box<str>: provide the same FromIterator implementations that String has, which can be implemented by collecting into a String and then calling into_boxed_str().

Additionally, impl FromIterator<Box<str>> for String and impl Extend<Box<str>> for String can be generalized to allow boxed strings with allocators other than Global. The implementations already copy the bytes to the String's allocation, so they work for Box<str, A> with any A: Allocator.

Motivation, use-cases

The existing impl<I> FromIterator<I> for Box<[I]> makes it convenient to collect an iterator into a boxed slice, for example:

let squares: Box<_> = (1..10).map(|x| x * x).collect();

Box<str> is an even more useful alternative to String than Box<[T]> is for Vec<T>, as strings are often immutable. The existing FromIterator<char> implementation for String makes it easy, for example, to reverse the characters in a string:

fn reverse(s: &str) -> String {
    s.chars().rev().collect()
}

However, returning a Box<str> requires a much more verbose implementation:

fn reverse(s: &str) -> Box<str> {
    s.chars().rev().collect::<String>().into_boxed_str()
}

Providing a FromIterator implementation for Box<str> would allow for the same implementation as for String.

Solution sketches

An implementation is available here: rust-lang/rust#99969
The same FromIterator implementations as for String are added for Box<str>. The implementations are straightforward, using String's FromIterator implementation and then calling into_boxed_str() to remove the excess capacity, analogous to impl<I> FromIterator<I> for Box<[I]>.

One other possibility is to extend the FromIterator implementations to Box<str, A> for all A: Allocator. But this is not currently done for Box<[T], A> or Vec<T, A>, so I opted to do the same and only add implementations for Box<str>.

Links and related work

rust-lang PR: rust-lang/rust#99969

What happens now?

This issue is part of the libs-api team API change proposal process. Once this issue is filed the libs-api team will review open proposals in its weekly meeting. You should receive feedback within a week or two.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    ACP-acceptedAPI Change Proposal is accepted (seconded with no objections)T-libs-apiapi-change-proposalA proposal to add or alter unstable APIs in the standard libraries

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions