Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multi-line string in Rust with preserved leading whitespace

In some languages it is possible to write something of this sort:

val some_string =
  """First line.
    | Second line, with leading space."""

That is, a multi-line string where all leading space is removed up to a point, but no further. This can be mimicked in Rust by writing:

let some_string = 
    "First line.\n \
     Second line, with leading space.";

However, this loses the benefit of looking closer to the actual output. Is there a way in Rust of writing something like the example pseudocode, preserving (some) leading whitespace?

like image 649
Pablo Avatar asked Oct 25 '15 20:10

Pablo


People also ask

How do you store multiline strings?

You will need to enclose it with a pair of Triple quotes, one at the start and second in the end. Anything inside the enclosing Triple quotes will become part of one multiline string. Let's have an example to illustrate this behavior. # String containing newline characters line_str = "I'm learning Python.

Can double quote strings span multiple lines?

A verbatim string literal consists of an @ character followed by a double-quote character, zero or more characters, and a closing double-quote character. Not only does this allow multiple lines, but it also turns off escaping.

What is multiline string literals?

Multiline String Literals. If you need a string that spans several lines, use a multiline string literal—a sequence of characters surrounded by three double quotation marks: let quotation = """ The White Rabbit put on his spectacles.

How do you declare a string in Rust?

String Literal For example, let company="Tutorials Point". String literals are found in module std::str. String literals are also known as string slices. The following example declares two string literals − company and location.


3 Answers

It is not supported by the language as of Rust 1.7 but 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 some_string = indoc! {"
    First line.
     Second line, with leading space."
};

It works for raw string literals as well.

let some_string = indoc! {r#"
    First line.
     Second line, with leading space."#
};

The result in both cases is "First line\n Second line, with leading space."

like image 109
dtolnay Avatar answered Oct 29 '22 21:10

dtolnay


No it's not possible (v1.3 and probably for a long time).

However, usually multi-line string literals that need to be human-readable are some sort of constant descriptions, like the usage string for a CLI program. You often see those things indented like this:

const USAGE: &'static str = "
Naval Fate.

Usage:
  ...
";

Which is ok I guess. If you have a lot of those strings or a really big one, you could use include_str!.

like image 28
Lukas Kalbertodt Avatar answered Oct 29 '22 22:10

Lukas Kalbertodt


You can start the line you want to indent with a ASCII quoted space \x20 or an Unicode quoted space \u{20}.

let some_string = 
    "First line.\n\
     \x20Second line, with leading space.\n\
     \u{20}Third line, with leading space.";

You just need to quote the first space.

let some_string = 
    "First line.\n\
     \x20 Second line, with two leading spaces.\n\
     \u{20} Third line, with two leading spaces.";
like image 34
ceving Avatar answered Oct 29 '22 20:10

ceving