I’ve recently been working on a Rust course for the Qvault app. In order to write a more engaging course, I want students to be able to write and execute code right in the browser. As I’ve learned from my previous posts on this topic, the easiest way to sandbox code execution on a server is to not execute code on a server. Enter Web Assembly, stage left.

For those of you who don’t care about how it works, and just want to give it a try, checkout the demo: Rust WASM Playground.

How It Works

The architecture is fairly simple:

  • User writes code in the browser
  • Browser sends code to server
  • Server adds some glue and compiles code to WASM
  • Server sends WASM bytes or compiler errors back to browser
  • Browser runs WASM and displays console output, or shows compiler errors

Writing code and shipping it to the server hopefully needs no explanation, it’s a simple text editor coupled with the fetch API. The first interesting thing we do is compile the code on the server.

Compiling the Code

Qvault’s server is written in Go. I have a simple HTTP handler with the following signature:

func (cfg config) compileRustHandler(w http.ResponseWriter, r *http.Request)

At the start of the function we unmarshal the code which was provided in a JSON body:

type parameters struct {
	Code string
}

decoder := json.NewDecoder(r.Body)
params := parameters{}
err := decoder.Decode(&params)
if err != nil {
	respondWithError(w, 500, "Couldn't decode parameters")
	return
}

Next, we create a temporary folder on disk that we’ll use as a “scratch pad” to create a Rust project.

usr, err := user.Current()
if err != nil {
	respondWithError(w, 500, "Couldn't get system user")
	return
}
workingDir := filepath.Join(usr.HomeDir, ".wasm", uuid.New().String())
err = os.MkdirAll(workingDir, os.ModePerm)
if err != nil {
	respondWithError(w, 500, "Couldn't create directory for compilation")
	return
}
defer func() {
	err = os.RemoveAll(workingDir)
	if err != nil {
		respondWithError(w, 500, "Couldn't clean up code from compilation")
		return
	}
}()

As you can see, we create the project under the .wasm/uuid path in the home directory. We also defer an os.RemoveAll function that will delete this folder when we are doing handling this request.

#golang #languages #rust #wasm #rust #rustlang #wasm #web assembly

Running Rust in the Browser with Web Assembly
8.75 GEEK