A very basic question about crates

I am starting a small project and crated a crate with the cargo. In this I have 3 mod files say foo1.rs, foo2.rs , foo3.rs and a test.rs file. The crates name is first_project. I have to pub mod these files all in a lib.rs file for everything to compile properly, I have found out about that through some hardship. But If I dont add ,say , use crate::foo1::{fun1,fun2} to my test.rs file, it won't see them inside the crate at all. Am I doing something wrong, I can't seem to find an explanation of this.

Sorry if the question looks too newbie-like, I started learning Rust just a few days ago...

Thanks for the help!

No need to apologise.

It sounds like you're describing files like this:

foo1.rs:

pub fn fun1() { ... }
pub fn fun2() { ... }

foo2.rs:

// contents are not relevant

foo3.rs:

// contents are not relevant

lib.rs:

pub mod foo1;
pub mod foo2;
pub mod foo3;

test.rs:

// It sounds like you're asking why the below line is needed?
use crate::foo1::{fun1, fun2};

fn test() {
    fun1();
    fun2();
}

In order to just call fun1 and fun2 like that, they need to be imported into the test module. If you don't want to import them into the test module, you instead have to fully specify their path. This should compile, for example:

fn test() {
    crate::foo1::fun1();
    crate::foo1::fun2();
}

Otherwise, how would it tell whether you wanted to call crate::foo1::func1, or wanted to call crate::foo2::func1?

1 Like

Thank you for the answer! Hmm true that makes sense. I realized that it was needed by following the compiler's directives ( tbh it is much more helpful than gcc or g++) but what I was curious why;
use foo1::{fun1,fun2};
wasn't working. Also am I supposed to declare the testing module in lib.rs too ?

1 Like

You can write tests like either:

// foo1.rs
pub fn fun1() { ... }

#[cfg(test)] 
mod foo1_tests {
    #[test]
    pub fn fun1_test() {
        // Test fun1 or anything else in here
    }
}

and not need to import anything or you can write them like so:

// test.rs
use crate::*;
#[cfg(test)]
pub mod tests_for_library {
    #[test]
    pub fn test_foo1() {
        //use foo1's fns here
        foo1::fun1();
    }
}

The reasoning behind needing to import your own crate is that the test.rs file is treated like a separate crate/library (but not really because it has access to the crate namespace) and it depends on your main library.

"use crate::*" imports everything. But is it possible to do "use foo1::{fun1,fun2};" ?

Please don't revive old posts like that. As for your question, the answer is yes, although you may need a crate:: before your foo1 in the path.

So I suppose there is no work around without using "crate::" in the beginning.

That is definitely the recommended approach, although for backwards compatibility the old syntax is still available if you turn off the 2018 edition.

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