DEV Community

Heechul Ryu
Heechul Ryu

Posted on

My First *.rs Other Than main.rs

In this post, I assume that you played with Rust at least a little bit.

When you first create a project with cargo init my-project, this is what you get out of the box.

❯ tree my-project
my-project/
├── src/
│  └── main.rs
└── Cargo.toml
Enter fullscreen mode Exit fullscreen mode

And you start writing code and it may look like this.

// src/main.rs

fn main() {
  Greet::hello();
}

struct Greet {
  // you may have some fields here
  // ...
}

impl Greet {
  fn hello() {
    println!("Hello, world!");
  }

  // let's pretend you have 100 more lines of some functions below
  //
  // fn foo(...) {
  // ...
}

// and there might be other stuff here for `main.rs`
Enter fullscreen mode Exit fullscreen mode

You check if this actually runs by cargo run and it outputs Hello, world!

It works OK but there are a couple of issues that may bug you.

  • 📜 the code for Greet struct is quite long (it's more than 100 lines!)
  • 🍯 you don't want to couple Greet struct and the other purpose functioning codes in main.rs which might happen without realizing if you keep them in the same file for long enough
  • 🏠 you don't want to read code for Greet stuff when you want to edit just main.rs and vice versa

So now you want the Greet struct to be on its own file so you moved things and it looks like these now.

// src/main.rs

fn main() {
  Greet::hello();
}

// `Greet` struct moved out from here
// ...

Enter fullscreen mode Exit fullscreen mode
// src/comm.rs (comm for communication)

// there are moved from `main.rs`
struct Greet {
  // ...
}

impl Greet {
  // ...
}
Enter fullscreen mode Exit fullscreen mode

You cargo run again but it doesn't work anymore. Does it?

At this point when I search google about how to split a struct into another file, I get all sorts of information and I'm sure they are very helpful but all I wanted to do right now is simply splitting a file into two or more so I can manage the code better. I don't know about you, but I'm not interested in learning about crates and all the other stuff just yet.

OK, let me see if I can make minimal changes to make it work... and tada!

  // src/main.rs

  // acknowledge `comm` module which corresponds to `comm.rs`
+ mod comm; 

  // use `Greet` struct from `comm` module
+ use comm::Greet;

  fn main() {
    Greet::hello();
  }

  // ...
Enter fullscreen mode Exit fullscreen mode
  // src/comm.rs

  // we add `pub`s for things to be accessible from other files like `main.rs`

- struct Greet {
+ pub struct Greet {
    // ...
  }

  impl Greet {
-   fn hello() {
+   pub fn hello() {
      println!("Hello, world!");
    }

    // ...
  }
Enter fullscreen mode Exit fullscreen mode

Now when you cargo run it should work like a charm :)

You probably have some questions about why mod comm; corresponds to comm.rs, and the answer is here, https://doc.rust-lang.org/rust-by-example/mod/split.html and the specific chunk in the link are below.

// This declaration will look for a file named `my.rs` or `my/mod.rs` and will
// insert its contents inside a module named `my` under this scope
mod my;
// ...
Enter fullscreen mode Exit fullscreen mode

I hope this was helpful (I actually wrote it for the future myself who always tends to forget particular details). Since I'm still a Rust (re)beginner, I might have not understood things correctly. When you have improvement suggestions on terms and expressions I used here or even a better way to approach the same problem, please let me know!

Discussion (0)