Skip to content

The string API should be more generic. #10827

Closed
@Kimundi

Description

@Kimundi

Current situation

Right now, many operation you can do with a string are hard coded to one specific type, like &str or char. For example:

let mut s = ~"";

s.push_str("foo");
s.push_char('a');

s.contains("foo");
s.contains_char('a');

Improving the API

Using traits and generics, these two examples could get boiled down into one contains and one push, which would accept either type while still being just as efficient as before.

There are quite a few methods that would benefit from such genericy, and so far I've identified two different kinds of traits:

  1. StrPushable - Anything that can be pushed to a string. String slices and char would implement this, but also things like Ascii could.
    Functions that would benefit from this include:

    push()
    replace()
    ...

    This might be implementable with fmt::Default instead, but I'm not sure if it's a good idea to do that, as it would mean you could push anything to a string that implements that trait.

  2. StrMatcher - Anything that could be used to find a string pattern in a string.
    Again, string slices and char would implement it, as well as predicate functions like |char| -> bool, the Ascii type, or things like a regex type.
    A trait like this already exists in a limited form with the CharEq trait, and would if properly extend be useful for a number of functions:

    split() // all variants
    replace()
    find()
    contains()
    ...

How it could look like

let mut s = ~"";

s.push("Hello");
s.push('!');
s.push(" aaa bbb ccc".as_ascii().to_upper());

assert_eq!(s, ~"Hello! AAA BBB CCC");

assert!(s.contains('!'));
assert!(s.contains(char::is_whitespace));
assert!(s.contains(regex("AA+")));

assert_eq!(s.split('!').collect(), ~["Hello", " AAA BBB CCC"]);
assert_eq!(s.split(char::is_whitespace).collect(), ~["Hello!", "AAA", "BBB", "CCC"]);
assert_eq!(s.split(regex("AA+")).collect(), ~["Hello! ", "A BBB CCC"]);

Status

I'm currently working on trying out this approach, to see if there are any rough edges or issues I haven't though of, but I think this would bring the string API a great step forward.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions