Rust Blocks

When you need to write raw Rust inside RustScript, use rust { }. It's an escape hatch for cases where RustScript's abstractions aren't enough.

Syntax

rust {
  println!("This is raw Rust code");
  let x: Vec<i32> = vec![1, 2, 3];
  for item in &x {
      println!("{}", item);
  }
}

Everything inside rust { } is emitted verbatim into the generated .rs file. No parsing, no transformation.

When to use it

Calling Rust APIs that don't have RustScript equivalents

rust {
  use std::fs;
  let contents = fs::read_to_string("config.toml").unwrap();
  println!("{}", contents);
}

Using Rust macros

rust {
  env!("CARGO_PKG_VERSION");
}

Performance-critical inner loops

function process(data: Array<i32>): i64 {
  // Normal RustScript for the API boundary
  let result: i64 = 0;

  rust {
    // Raw Rust for the hot path
    for chunk in data.chunks(4) {
        let sum: i64 = chunk.iter().map(|x| *x as i64).sum();
        result += sum;
    }
  }

  return result;
}

Complex trait implementations

When you need a trait impl that RustScript can't express:

rust {
  impl std::fmt::Display for MyType {
      fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
          write!(f, "MyType({})", self.value)
      }
  }
}

Rules

  • Code inside rust { } is emitted as-is. You're responsible for its correctness.
  • You can reference variables and types from the surrounding RustScript code.
  • Rust blocks appear at the same scope level in the generated code.
  • Syntax errors in rust blocks show up as rustc errors, not RustScript compiler errors.

When NOT to use it

Don't reach for rust { } as a first resort. RustScript covers:

  • All standard control flow
  • String, Array, Map, Set operations
  • Async/await with tokio
  • Crate imports
  • JSON serialization
  • Error handling

Use rust { } only when you genuinely need something outside RustScript's coverage. The more RustScript code you write, the more the compiler can help you with ownership, type checking, and diagnostics.

Ejecting

If you find yourself writing a lot of rust blocks, you might be ready to eject to pure Rust:

rustscript eject

This converts the project to a standard Cargo project: the generated .rs files become the source of truth, rustscript.json is removed, and you continue in pure Rust. The generated code is idiomatic and human-readable -- a clean starting point. No lock-in.