Search code examples
functionrusttypes

Function needs to accept multiple types in one input parameter


I'm working in rust to make a program that will automatically solve chemical equations (and other related things) for me. Long story short I asked my chemistry teacher if he would let me do that and use it on homework, and he said yes, as long as I wrote it myself. I've been looking at the rust language for a while now, and I figured this would be as good a time as any to learn. So in my project I have a struct defined as so:

pub struct Element<> {
    pub count: i32,
    pub name: String
}

and a function to build an Element defined as so:

pub fn element(count: i32, name:String) -> Element<> {
    let equ: Element = Element { count: count, name: name };
    return equ
}

This is all fine and dandy, but a frustration arose as I started doing unit tests; strings created like so:
let xyz = "xyz"
are &str by default. This meant that I had to type .to_string() after every single manually defined string (which I do a lot in my unit tests). As a progammer, minor inconvinience that will take longer to automate than to deal with manually is my bane (as I'm sure you all know), so I tried redefining the function like so:

pub fn element(count: i32, name: &str) -> Element<> {
    let equ: Element = Element { count: count, name: name.to_string() };
    return equ
}

Easy! Now the function handles the stringing for me! what joy!.. except that now when something is already a string, and I want to add it to an element, like, I don't know, every single non unit test implementation of this function?, I have to turn it into an &str.

Seeing as avoiding this sort of thing was the whole purpose of this venture in the first place, I started looking for ways to fix it, but I just couldn't find anything. Traits looked promising, but I can't pass in arguments the way I want to. I saw something about defining multiple functions, but I can't seem to get it to work. Defining an enum would work, but that forces me to wrap the input string in the enum, which is more work than just .to_string(), which defeats the whole purpose.

Thanks in advance for the help! and please tell me if any clarification is needed.


Solution

  • Converting a String to &str is as simple as adding an ampresand: &string. I don't think this justifies a change.

    However, if you are concerned with the performance of cloning the string unnecessarily, you can take impl Into<String> (that accepts both String and &str) and turn it into String via .into():

    pub fn element(count: i32, name: impl Into<String>) -> Element {
        Element { count, name: name.into() }
    }