rustproject-structure

How should I structure a Rust project for solving small coding challenges?


I have been doing Project Euler problems (mathematical coding challenges) for a while.

In the past I have been coding them up in Python (where it is simple to have dozens of scripts in the same project). However, I am now redoing some of the challenges as I learn Rust. I have found it pretty awkward to work on these projects as I can't simply write a bunch of Rust programs in the same directory but it also seems very excessive to create a whole new Rust project for each program.

Can anyone recommend a good intermediary? Ideally I'm looking for something similar to the aforementioned Python project with a bunch of separate scripts.


Solution

  • I would recommend this project structure for working through coding challenges:

    /src/bin/problem-101.rs
    /src/bin/problem-143.rs
    /src/lib.rs
    /Cargo.toml
    

    Essentially just create a project like cargo new --lib challenges, create a bin/ folder in src/, create separate source files for each problem in there, and off you go!

    //! /src/bin/problem-101.rs
    fn main() {
        println!("solution #101")
    }
    
    //! /src/bin/problem-143.rs
    fn main() {
        println!("solution #143")
    }
    
    //! /src/lib.rs
    pub fn add(left: usize, right: usize) -> usize {
        left + right
    }
    
    # Cargo.toml
    [package]
    name = "challenges"
    version = "0.1.0"
    edition = "2021"
    
    [dependencies]
    # dependencies are shared between all problems
    

    This structure is easy to use and extend with small "scripts" because Rust source files in the /src/bin folder are automatically detected as binaries and do not need to be listed separately in Cargo.toml. You can run them directly:

    > cargo run --bin problem-101
       Compiling challenges v0.1.0 (...\challenges)
        Finished dev [unoptimized + debuginfo] target(s) in 0.26s
         Running `target\debug\problem-101.exe`
    solution #101
    > cargo run --bin problem-143
       Compiling challenges v0.1.0 (...\challenges)
        Finished dev [unoptimized + debuginfo] target(s) in 0.32s
         Running `target\debug\problem-143.exe`
    solution #143
    

    Using a library as the root of the project allows you to share functions and logic between your problems very easily. Just import from the library like so:

    use challenges::add;
    

    The only step up from here would be to use workspaces which would give you fine-grained dependencies for each problem, but that requires separate folders, separate Cargo.tomls, separate src/ directories so you probably don't want that for simple coding challenges.