Template literals

If you've been paying attention on previous sections you might have seen odd looking strings like `Hello ${name}`. These are called template literals, and allow you to conveniently build strings using variables from the environment.

Template literals are a concept borrowed from EcmaScript.

let age = 30; dbg!(`I am ${age} years old!`);
$> cargo run -- run scripts/book/template_literals/basic_template.rn "I am 30 years old!"

Template strings are accelerated by the Vm, each argument uses a display protocol and it can be very efficient to build complex strings out of it.

The DISPLAY_FMT protocol

The DISPLAY_FMT protocol is a function that can be implemented by any external type which allows it to be used in a template string.

It expects a function with the signature fn(&self, buf: &mut String) -> fmt::Result.

use rune::{ContextError, Module}; use rune::runtime::{Protocol, Formatter}; use std::fmt::Write as _; use std::fmt; #[derive(Debug)] pub struct StatusCode { inner: u32, } impl StatusCode { #[rune::function(protocol = DISPLAY_FMT)] fn display_fmt(&self, f: &mut Formatter) -> fmt::Result { write!(f, "{}", self.inner) } } pub fn module() -> Result<Module, ContextError> { let mut module = Module::new(["http"]); module.function_meta(StatusCode::display_fmt)?; Ok(module) }

This is what allows status codes to be formatted into template strings, any types which do not implement this protocol will fail to run.

let vec = [1, 2, 3]; dbg!(`${vec}`);
$> cargo run -- run scripts/book/template_literals/not_a_template.rn == ! (`Vec` does not implement the `display_fmt` protocol (at 5)) (77.7µs) error: virtual machine error ┌─ scripts/book/template_literals/not_a_template.rn:3:9 │ 3 │ dbg!(`${vec}`); │ ^^^^^^^^ `Vec` does not implement the `display_fmt` protocol