How can i solve: format argument must be a string literal

Hello Everyone :slight_smile:

Why am i getting this error?

 error: format argument must be a string literal
  --> play.rs:13:27
   |
13 |     let request = format!(headers.join("\r\n"), "/Matrix/");
   |                           ^^^^^^^^^^^^^^^^^^^^
help: you might be missing a string literal to format with
   |
13 |     let request = format!("{} {}", headers.join("\r\n"), "/Matrix/");
   |                           ^^^^^^^^

error: aborting due to previous error


shell returned 1

Press ENTER or type command to continue

The code

use std::net::TcpStream;
use std::io::Result;

fn main() -> Result<()> {
    let headers = [
        "GET http://192.168.0.104{} HTTP/1.1",
        "\r\n",
    ];

    let stream = TcpStream::connect("192.168.0.104:80")?;
    let buf = String::new();

    let request = format!(headers.join("\r\n"), "/Matrix/");

    // stream.write_all(request.as_bytes());

    Ok(())
}

The first argument of the print!, println!, write!, writeln!, format!, etc. macros must be a literal format string. It's just how the macros was defined. If you do what the compiler suggests, the code will compile.

is there another way to pass a variable as first argument that contains the text to be formatted, other than using macros, more like printf in c?

1 Like

No, it seems Rust's printing/formatting macros only accepts a literal as first argument. You can use the + operator, though:

let request = headers.join("\r\n") + "/Matrix/";

I'm not a C programmer, so I searched a bit to try to see how printf works. I found that the C compiler warns if you use a non-literal format string, because it had been exploited in the past: stackoverflow

1 Like

Thanks @L0uisc i've change it to

stream.write(format!("GET {} HTTP/1.1\r\n\r\n", path).as_bytes()).unwrap();

You can also look into concat macro crate if you want to construct the headers' template string in more ergonomic way.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.