Is there any such thing as `str!("Hello world.")` instead of `"...".into_string()`?


#1

Hello Rustaceans,

I’m currently working on an SMTP server library and feel like I’m writing a lot of things like "some string".into_string(). That seems redondant and I find into_string() to be quite long. I tried using box "some string" but that yields a Box<&str>, which is not what I want.

Is there any such thing as str!("some string"), where str! is a macro that basically calls into_string()?

I feel like this would make things a bit more readable. What do you think?


#2

It’s something that pretty easy to do yourself. Thats the great thing about macros and syntax extensions, you can add your own sugar without having to bloat the language or the standard libraries.

#![feature( macro_rules )]

macro_rules! str(
    ($s:expr) => ( String::from_str( $s ) );
)

fn main() {
    let mut s = str!( "Hello " );

    s.push_str( "World" );

    println!("{}", s);
}

#3

This doesn’t actually need to be a macro.

fn str(s: &str) -> String { String::from_str(s) }

works fine.


#4

Yes, it’s true that it’s trivial to implement. I was just wondering if something like that was already there. Thanks for the suggestions :sunny:


#5

I usually use format!("str")


#6

I like this one too, but I think that format!() must use some kind of parsing of the string before formatting it, no? Is there any overhead involved?


#7

Why use a macro when a function or method (to_s) is enough? Using foo!(x) instead of foo loses the sane scoping system and obscures meaning.


#8

My goal isn’t so much to find a macro than it is avoiding .into_string() every single time. Any concise solution is good. I don’t see any function named .to_s() in the docs though. What are you referring to?


#9

You can define a method called to_s. If it’s too verbose then it should be renamed in the standard libraries though.


#10

I think syntax that prepending an ‘s’ before string literal like s"it is a String" would be better. parser will convert s"xxx" to “xxx”.s()


#11

That’s an interesting idea. One drawback is this requires changes to the parser. But apart from that, I like it ! :smile:


#12

"xxx".to_string() => s"xxx" is a great simplify.


#13

I wonder how often people would use s"foobar" because they saw it elsewhere, when a static str would have sufficed.


#14

That’s exactly what happened with ~“foobar”. It was over-used by far.


#15

Hadn’t thought about over use. This makes sense.

Has the removal of the sigil resulted in less over use ?


#16

Hy, if I am not wrong into_string from StrExt is deprecated and .to_owned() should be preferred (but there is also a IntoString and a ToString trait…). Thought generally having a macro witch just calls a method on the passed value sounds like a bad idea.

But due to the frequent usage of str with to_string, into_string and to_owned I think the existence of a standard macro like owned! is justified maybe even preferable. Also reading owned!("hallo") pretty clearly says what is does and looks more clear than a lot of .to_owned() calls and is less ambiguous then a str!("halo") macro.


#17

Why does this need to be a macro rather than a function?


#18

@benh you are right maybe a importable function like:

#[inline(always)]
fn owned(value: &str) -> String {
    value.to_owned()
}

Would be better. Or the generic equivalent:

#[inline (always)]
fn owned<O, Sized? T: ToOwned<O>>(value: &'static T) -> O {
    value.to_owned()
}