I am trying to configure an example project in Rust to work.
My structure is:
src/potter.rs
tests/tests.rs
And my Cargo.toml
[package]
name = "potter"
version = "0.1.0"
authors = ["my name"]
[dependencies]
My potter.rs
contains:
pub mod potter {
pub struct Potter {
}
impl Potter {
pub fn new() -> Potter {
return Potter {};
}
}
}
And my tests.rs
contains:
use potter::Potter;
#[test]
fn it_works() {
let pot = potter::Potter::new();
assert_eq!(2 + 2, 4);
}
But I receive this error:
error[E0432]: unresolved import `potter`
--> tests/tests.rs:1:5
|
1 | use potter::Potter;
| ^^^^^^ Maybe a missing `extern crate potter;`?
error[E0433]: failed to resolve. Use of undeclared type or module `potter`
--> tests/tests.rs:6:19
|
6 | let pot = potter::Potter::new();
| ^^^^^^ Use of undeclared type or module `potter`
warning: unused import: `potter::Potter`
--> tests/tests.rs:1:5
|
1 | use potter::Potter;
| ^^^^^^^^^^^^^^
|
= note: #[warn(unused_imports)] on by default
If I add extern crate potter;
, it doesn't fix anything...
error[E0463]: can't find crate for `potter`
--> tests/tests.rs:1:1
|
1 | extern crate potter;
| ^^^^^^^^^^^^^^^^^^^^ can't find crate
Go back and reread The Rust Programming Language about packages, crates, modules and the filesystem.
Common pain points:
Every programming language has its own way of dealing with files — you cannot just assume that because you've used any other language that you will magically get Rust's take on it. That's why you should go back and re-read the book chapter on it.
Each file defines a module. Your lib.rs
defines a module of the same name as your crate; a mod.rs
defines a module of the same name as the directory it's in; every other file defines a module of the name of the file.
The root of your library crate must be lib.rs
; binary crates may use main.rs
.
No, you really shouldn't try to do non-idiomatic filesystem organization. There are tricks to do most anything you want; these are terrible ideas unless you are already an advanced Rust user.
Idiomatic Rust does not generally place "one type per file" like many other languages. Yes, really. You can have multiple things in one file.
Unit tests usually live in the same file as the code it's testing. Sometimes they will be split out into a file containing the submodule, but that's uncommon.
Integration tests, examples, benchmarks all have to import the crate like any other user of the crate and can only use the public API.
To fix your issue:
src/potter.rs
to src/lib.rs
.pub mod potter
from src/lib.rs
. Not strictly required, but removes needless nesting of modules.extern crate potter
to your integration test tests/tests.rs
. filesystem
├── Cargo.lock
├── Cargo.toml
├── src
│ └── lib.rs
├── target
└── tests
└── tests.rs
src/lib.rs
pub struct Potter {}
impl Potter {
pub fn new() -> Potter {
Potter {}
}
}
tests/tests.rs
use potter::Potter;
#[test]
fn it_works() {
let pot = Potter::new();
assert_eq!(2 + 2, 4);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With