How to organize a Rust project

Hi all,

I am trying to figure out how to build organized programs in Rust, and was curious about best practices about this. I have the following crate structure (binary):

src
->object
  ->mod.rs
  ->sphere.rs
-> main.rs
-> cargo.toml

The idea is that object should have a general custom trait Hitable and each “type” of object, for example, a Sphere would implement it.

object/mod.rs:
pub mod sphere;

pub trait Hitable {
    fn intersect(&self) -> f64;
}
object/sphere.rs:

use crate::object;

pub struct Sphere {
    pub  radius : f64
}

impl object::Hitable for Sphere {
    fn intersect(&self) -> f64 {
        self.radius
    }
}
main.rs
mod  object;
use crate::object::sphere::Sphere as Sphere;

use object::Hitable;
fn main() {

    let sphere = Sphere {
        radius : 20.0
    };

    println!("Hello, world! {}", sphere.intersect());
}

This is the toy program setup I have right now. I had a few questions about this:

  1. Am I doing the module import paradigm right? The Book only talks about organizing code by splitting it into multiple .rs files, but I did not seem to find any info on how to handle source files in multiple folders. Any tips and ideas would be appreciated!

  2. In main.rs, it’s rather difficult to use the Sphere struct, as in, the use line seems a bit long. Is there a better way to import and organize this?

Thanks in advance!

This is a reasonable file layout, except I think most real multifile projects should be libs with a few scripts in src/bin. But for a toy this is absolutely fine.

You don’t need as Sphere here, that is what you’d get without an alias.

Yes, it’s there. Submodules must live in subdirs named after their parent modules. The file hierarchy necessarily matches the module hierarchy in Rust. You are doing it correctly.

Thanks a lot for your reply!

I see! However, that declaration path seems rather long-winded. If I want to use a Sphere object inside main.rs is that the only way to do it given the current structure? Or is there some shorthand notation?

Also, if possible, could you please give me example of a bigger project that makes use of the libs+scripts in src/bin format so I can study them? Thanks!

Yes, you have to import it like that. When you have more to import from your own crate you can use nested paths to save a little typing. I think the only other option here is that your whole crate is automatically implicitly into main.rs, which would be terrible.

I can’t think of an example off the top of my head - and my own projects are all private for now, but the crate layout is described here: https://doc.rust-lang.org/cargo/guide/project-layout.html

This is an opinion rather than a hard rule, but I find that any script beyond a few hundred lines should be turned into a library that gets imported and called by a tiny script.

Awesome, thanks for the link!

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.