Multiple `Into<String>`s for a function


#1

I’ve got a lot of string-like arguments for which I want to accept String, &str, etc.

The signature currently looks like this:

pub fn new<S1, S2, S3, S4, S5, S6>(document_type: S1, uid: UID, pid: PID, title: S2, url: S3, abstract_text: S4, description: S5, content: S6) -> Self
    where S1: Into<String>,
          S2: Into<String>,
          S3: Into<String>,
          S4: Into<String>,
          S5: Into<String>,
          S6: Into<String> {
    /* ... */
}

How can I make this better?


#2

Why aren’t you just using a single type parameter S?

As a side note, depending on your usage, you might want to look into using AsRef<str>.

(e) Oh, ok, I see why you’d want to use several parameters. I don’t think there’s a better way if you need this flexibility and don’t want to go into dynamic dispatch.


#3

I’m using the function to populate a new struct instance. Is AsRef<str> interesting in this scenario?


#4

If you don’t mind needlessly copying a String, you could do something like this https://play.rust-lang.org/?gist=d20f4245f99f7c5f64ed2ae004642773&version=stable. I just have to admit that I’m now having trouble making it work with a 2nd argument to put a String into, here’s what I had in mind: https://play.rust-lang.org/?gist=ae2b1ce423c9d7e9c87e850bf070335e&version=stable. Maybe someone else can chime in how to do this correctly.

Truth be told though, even if that works, I’d just keep your original version.


#5

You can use type erasure:

fn new(x: &ToString, y: &ToString, ...)

#6

And here I was meddling with &Into<String> which is not possible. Thanks!


#7

Into<String> and ToString are not at all alike…

Implementors of ToString:

  • Implementors of Into<String>
  • Integers
  • Floats
  • Errors

&AsRef<str> might be closer in intent.