How to create a Rust Lab?
Coding labs are a powerful feature of Fermion. By integrating coding labs into your platform, you can enhance user retention, provide hands-on experience, and encourage a learn-by-doing approach.
This guide walks you through setting up a Rust interactive coding lab.
Step 1 - Creating the Lab
- Add a new item lab in your course curriculum page
- A new lab item gets added. Edit the lab using the controls:
- A lab item in a course can be attached to an existing lab you created in the past. If not, you can create a new lab with this Edit interface:
- You should now be able to write a quick lab name and press on "Create Lab" button. Once you do, press on
Attach to course item
button. Once that is done, click the three dots again and click on "Edit" to edit the lab.
Step 2 - Lab Instructions
Once you click on Edit
button a new page will open. On this page you need to setup instructions for lab. These instructions would be visible to the user when they're attempting the lab. Therefore, include all the helper material, lab setup instructions here.
Step 3 - Lab Defaults
Lab defaults define the initial environment setup for the lab. It is crucial to configure this correctly to avoid confusing students.
For Rust labs, the playground must initialize a valid Rust project. You can do this by specifying a Git repository and branch with a basic Cargo
project structure:
INFO
We recommend forking this repository: Rust playground starter.
This repository contains a minimal Rust project with a Cargo.toml
file and a src/main.rs
file. Once forked, update the repository link in your lab settings.
The repository also includes a .cdmrc
file, a critical configuration file for Fermion labs. Familiarize yourself with the .cdmrc guide to understand how it works before proceeding.
Step 4 - Evaluation Script
The evaluation script is executed when the user clicks the "Run Tests" button in the playground. It runs the test cases written for the lab.
Here’s a sample bash script for a Rust lab:
#!/bin/bash
set -e 1
# Create a `.labtests` directory to store test files
mkdir -p /home/damner/code/.labtests
# Move the provided test file into the `.labtests` folder
mv $TEST_FILE_NAME /home/damner/code/.labtests/test.rs
cd /home/damner/code/.labtests;
rustc test.rs && ./test
- We simply download the test file (we create in next step), and run it with
rustc
Step 5 - Test File
In the "Custom Test File" section of the lab, you can define test cases to validate the user's code.
Here’s a sample Rust test file:
// Include the user's default `lib.rs` file as usercode module
#[path = "/home/damner/code/src/lib.rs"]
mod usercode;
use usercode::*;
use std::env;
use std::fs::File;
use std::io::Write;
fn main() {
let mut results = Vec::new();
// Test 1
results.push(run_test(|| {
let a = 1;
let b = 2;
let res = add(a, b);
res == 3
}));
// Test 2
results.push(run_test(|| {
let a = 2;
let b = 3;
let res = add(a, b);
res == 5
}));
// Get output file path from environment variable
let output_file = env::var("UNIT_TEST_OUTPUT_FILE")
.expect("Environment variable UNIT_TEST_OUTPUT_FILE must be set");
// Write results to the specified file in JSON format
if let Err(e) = write_results_to_file(&results, &output_file) {
eprintln!("Failed to write results to {}: {}", output_file, e);
}
}
fn run_test<F>(test_fn: F) -> bool
where
F: FnOnce() -> bool,
{
test_fn()
}
fn write_results_to_file(results: &[bool], file_path: &str) -> std::io::Result<()> {
// Manually format the boolean array as a JSON string
let json_results = format!(
"[{}]",
results
.iter()
.map(|&b| b.to_string()) // Convert bool to "true"/"false"
.collect::<Vec<_>>()
.join(", ")
);
// Write the JSON string to the file
let mut file = File::create(file_path)?;
file.write_all(json_results.as_bytes())?;
Ok(())
}
Key Points
- The length of boolean array
results
must match the challenges defined in the UI. - Tests must be executed sequentially and in order. This is because the boolean array you write to the output file must match the order in which you add challenges in the UI. This is why we don't use
cargo test
and instead run a rust script manually.
Step 6 - Add Challenges
In the Fermion UI, define the challenges corresponding to the tests. Ensure the order of challenges matches the order of test cases in your test file.
For example:
- Challenge 1: Verify the
add
function works correctly with input 1,2. - Challenge 2: Verify the
add
function works correctly with input 2,3.
This mapping ensures that the playground accurately reflects the user's progress.
Your interactive Rust lab is now ready! Students will be able to practice and learn Rust through real-world challenges, with tests running in a predictable, sequential order.