0

I'm about to run into the wall to end the pain - how does Rust finds its dependencies? How does it use module namespaces? I simply don't understand, and the compiler is just being cryptic, and the documentation is... ehm... making assumptions about what it is I'd like to do, not explaining the plumbing. Can't be that difficult. And not everybody wants to write a helloworld.

So, I want to make a library and I have a lib.rs (using cargo new --lib), and I have a few files in the same directory that I want to include (called something.rs). The concept is that lib.rs contains all the access methods, and the files sitting in the same directory, implement not directly accessible methods and helper structures. That should be as simple as 'use something' right? Nope. Compiler says no (I use 'cargo build'): 'Unresolved import'. 'No something in the root'. I've tried with and without 'crate::'. I've tried 'using' the secondary file, and then the individual modules / types in the file. I've tried subdirs of the same name. I've tried putting 'mod' around my code with the same name as the file, and with the same name as the module name I'm wanting to have. Nothing. It's frustrating to say the least and when I scan the internet for the error messages I'm getting, I'm clearly not very alone.

Is there a way to make the compiler be a bit more verbose. For example, give me an idea of how it's building up an internal idea of namespacing, or what its search paths are, for example?

Example:

#!/bin/sh

set -e

rm -rf /tmp/foo

cd /tmp
cargo new foo --lib
#find /tmp/foo

echo "
use bar;

pub fn foobar
  ()
{
  barfoo();
}
" >> /tmp/foo/src/lib.rs

echo "
fn barfoo
  ()
{
}
" > /tmp/foo/src/bar.rs

cd /tmp/foo
cargo build

Knowledge level increased, but now the compiler wants me to create a subdirectory, which I don't understand:

#!/bin/sh

set -e

rm -rf /tmp/foo
cd /tmp
cargo new foo --lib

echo "
mod bar;
use bar::barfoo;

pub fn foobar
  ()
{
  barfoo();
}
" >> /tmp/foo/src/lib.rs

echo "
mod barfu;
use barfu::something;

pub fn barfoo
  ()
{
  something();
}
" > /tmp/foo/src/bar.rs

echo "
mod bar;
use bar::barfoo;

pub fn something
  ()
{
  barfoo();
}
" > /tmp/foo/src/barfu.rs

cd /tmp/foo
cargo build
  • `mod foo;` in your `lib.rs` will tell Rust that you have a `foo.rs` that contains the `foo` module. `use foo;` or `use foo::something;` in your `lib.rs` will import the contents of the module into the current namespace. `pub use foo` or `pub use foo::something` in your `lib.rs` will do the same, and additionally re-export it as the public API of your library. I don't see how it could be simpler than that (but I do remember being confused in a similar way when I was just starting). Does that help? – user4815162342 Mar 20 '21 at 09:53
  • I think this article does a good job of explaining things: [Clear explanation of Rust’s module system](http://www.sheshbabu.com/posts/rust-module-system/). – kmdreko Mar 20 '21 at 09:59
  • I made a shell script to illustrate my problem. I think that what I'm doing is intuitive, but I may be wrong. I've tried some tweaks to this code as well, but none of it compiles. I'll add it as a non-comment. – Kees-Jan Hermans Mar 20 '21 at 12:39
  • Replace (1) `use bar;` → `mod bar;` (2) `barfoo();` → `bar::barfoo();` and (3) `fn barfoo` → `pub fn barfoo`. If you [first create the module in-line](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=956d1b88c6698d6bdaf8f85303bbe992), once you get that working, breaking `mod bar` out into a separate file is pretty much trivial. – trent Mar 20 '21 at 13:44
  • Ok. But now it doesn't work when the dependency has yet another dependency. Then the compiler wants me to create a subdirectory. – Kees-Jan Hermans Mar 20 '21 at 15:25
  • Using `mod name;` to declare modules for *sibling* files only works in the root level `main.rs`/`lib.rs` or nested `mod.rs` files. – kmdreko Mar 20 '21 at 16:44
  • That makes sibbling files somewhat less portable, doesn't it? – Kees-Jan Hermans Mar 20 '21 at 21:28
  • Less portable how? Like, you can't put `mod name;` in two different files? If you use `mod` twice you get *two unrelated modules*, not the same module imported in two places. For the second thing you need at least one of them to be a `use` instead of `mod`. – trent Mar 22 '21 at 19:14
  • Less portable in that sibbling dependency is then something that you may have to re-plumb, with declarations inside the file itself, when you take a module elsewhere. – Kees-Jan Hermans Mar 26 '21 at 10:53

0 Answers0