Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Choosing where newlines are in a multi-line string literal

Tags:

rust

If I create the following multi-line string literal:

let lit = "A -> B
           C -> D
           E -> F";

It prints out like this:

A -> B
          C -> D
          E -> F

No surprise. However, if I try this:

let lit = "A -> B\
           C -> D\
           E -> F";

I get:

A -> BC -> DE -> F

What I'm trying to get is this:

A -> B
C -> D
E -> F

But this is the best thing I've come up with:

let lit = "A -> B\n\
           C -> D\n\
           E -> F";

Or maybe this:

let lit = vec!["A -> B", "C -> D", "E -> F"].connect("\n");

Both of those feel a little clunky, though not terrible. Just wondering if there's any cleaner way?

like image 896
anderspitman Avatar asked Aug 04 '15 02:08

anderspitman


1 Answers

Indoc is a procedural macro that does what you want. It stands for "indented document." It provides a macro called indoc!() that takes a multiline string literal and un-indents it so the leftmost non-space character is in the first column.

let lit = indoc! {"
    A -> B
    C -> D
    E -> F"
};

The result is "A -> B\nC -> D\nE -> F" as you asked for.

Whitespace is preserved relative to the leftmost non-space character in the document, so the following preserves 2 spaces before "C":

let lit = indoc! {"
    A -> B
      C -> D
    E -> F"
};

The result is "A -> B\n C -> D\nE -> F".

like image 72
dtolnay Avatar answered Oct 16 '22 05:10

dtolnay