Can't import a module from another crate - unresolved import - rust

I am trying to write a crate called bar, the structure looks like this
src/
├── bar.rs
└── lib.rs
My src/lib.rs looks like this
#![crate_type = "lib"]
#![crate_name = "bar"]
#![feature(ip_addr)]
#[allow(dead_code)]
pub mod bar;
My bar.rs has
pub struct baz {
// stuff
}
impl baz {
// stuff
}
Now when I try to use this crate in another crate like:
extern crate bar;
use bar::baz;
fn main() {
let cidr = baz::new("Hi");
println!("{}", cidr.say());
}
This fails with
error: unresolved import `bar::baz`. There is no `baz` in `bar`
Do I need to declare the module somewhere else?

The important part you are missing is that crates define their own module. That is, your crate bar implicitly defines a module called bar, but you also have created a module called bar inside that. Your struct resides within this nested module.
If you change your main to use bar::bar::baz; you can progress past this. You will have to decide if that's the structure you want though. Most idiomatic Rust projects would not have the extra mod and would flatten it out:
src/lib.rs
pub struct Baz {
// stuff
}
impl Baz {
// stuff
}
Unfortunately, your example code cannot compile, as you have invalid struct definitions, and you call methods that don't exist (new), so I can't tell you what else it will take to compile.
Also, structs should be PascalCase.

Related

How do I import a file from a folder in main?

I have such a directory structure:
structs
-book.rs
main.rs
I just read about modules and am trying to import a structure from book.rs in main:
book.rs
#[derive(Debug)]
pub struct book{
pub title:u32
}
main.rs
mod book;
fn main() {
print!("start")
}
And this causes an error: unresolved module, can't find module file: book.rs , or book/mod.rs
I tried in different ways, but it doesn't work out. I will be glad of help to understand what the error is.
You need to make structs a module to be able to import things.
structs
-book.rs
-mod.rs
main.rs
main.rs
mod structs;
use crate::structs::book::book;
fn main() {
let b = book {
title: "The Rust Programming Language".to_string(),
};
print!("{:?}", b);
}
structs/mod.rs
pub mod book;
structs/book.rs
#[derive(Debug)]
pub struct book{
pub title: String,
}
You should also change book to be Book when you define the struct since structs should be in PascalCase not camelCase or snake_case

Is there a way to use only one namespace qualifier when importing modules in Rust? [duplicate]

I am trying to write a crate called bar, the structure looks like this
src/
├── bar.rs
└── lib.rs
My src/lib.rs looks like this
#![crate_type = "lib"]
#![crate_name = "bar"]
#![feature(ip_addr)]
#[allow(dead_code)]
pub mod bar;
My bar.rs has
pub struct baz {
// stuff
}
impl baz {
// stuff
}
Now when I try to use this crate in another crate like:
extern crate bar;
use bar::baz;
fn main() {
let cidr = baz::new("Hi");
println!("{}", cidr.say());
}
This fails with
error: unresolved import `bar::baz`. There is no `baz` in `bar`
Do I need to declare the module somewhere else?
The important part you are missing is that crates define their own module. That is, your crate bar implicitly defines a module called bar, but you also have created a module called bar inside that. Your struct resides within this nested module.
If you change your main to use bar::bar::baz; you can progress past this. You will have to decide if that's the structure you want though. Most idiomatic Rust projects would not have the extra mod and would flatten it out:
src/lib.rs
pub struct Baz {
// stuff
}
impl Baz {
// stuff
}
Unfortunately, your example code cannot compile, as you have invalid struct definitions, and you call methods that don't exist (new), so I can't tell you what else it will take to compile.
Also, structs should be PascalCase.

include module from the same directory level [duplicate]

If you have a directory structure like this:
src/main.rs
src/module1/blah.rs
src/module1/blah2.rs
src/utils/logging.rs
How do you use functions from other files?
From the Rust tutorial, it sounds like I should be able to do this:
main.rs
mod utils { pub mod logging; }
mod module1 { pub mod blah; }
fn main() {
utils::logging::trace("Logging works");
module1::blah::doit();
}
logging.rs
pub fn trace(msg: &str) {
println!(": {}\n", msg);
}
blah.rs
mod blah2;
pub fn doit() {
blah2::doit();
}
blah2.rs
mod utils { pub mod logging; }
pub fn doit() {
utils::logging::trace("Blah2 invoked");
}
However, this produces an error:
error[E0583]: file not found for module `logging`
--> src/main.rs:1:21
|
1 | mod utils { pub mod logging; }
| ^^^^^^^
|
= help: name the file either logging.rs or logging/mod.rs inside the directory "src/utils"
It appears that importing down the path, i.e. from main to module1/blah.rs works, and importing peers, i.e. blah2 from blah works, but importing from the parent scope doesn't.
If I use the magical #[path] directive, I can make this work:
blah2.rs
#[path="../utils/logging.rs"]
mod logging;
pub fn doit() {
logging::trace("Blah2 invoked");
}
Do I really have to manually use relative file paths to import something from a parent scope level? Isn't there some better way of doing this in Rust?
In Python, you use from .blah import x for the local scope, but if you want to access an absolute path you can use from project.namespace.blah import x.
I'm going to answer this question too, for anyone else who finds this and is (like me) totally confused by the difficult-to-comprehend answers.
It boils down to two things I feel are poorly explained in the tutorial:
The mod blah; syntax imports a file for the compiler. You must use this on all the files you want to compile.
As well as shared libraries, any local module that is defined can be imported into the current scope using use blah::blah;.
A typical example would be:
src/main.rs
src/one/one.rs
src/two/two.rs
In this case, you can have code in one.rs from two.rs by using use:
use two::two; // <-- Imports two::two into the local scope as 'two::'
pub fn bar() {
println!("one");
two::foo();
}
However, main.rs will have to be something like:
use one::one::bar; // <-- Use one::one::bar
mod one { pub mod one; } // <-- Awkwardly import one.rs as a file to compile.
// Notice how we have to awkwardly import two/two.rs even though we don't
// actually use it in this file; if we don't, then the compiler will never
// load it, and one/one.rs will be unable to resolve two::two.
mod two { pub mod two; }
fn main() {
bar();
}
Notice that you can use the blah/mod.rs file to somewhat alleviate the awkwardness, by placing a file like one/mod.rs, because mod x; attempts x.rs and x/mod.rs as loads.
// one/mod.rs
pub mod one.rs
You can reduce the awkward file imports at the top of main.rs to:
use one::one::bar;
mod one; // <-- Loads one/mod.rs, which loads one/one.rs.
mod two; // <-- This is still awkward since we don't two, but unavoidable.
fn main() {
bar();
}
There's an example project doing this on Github.
It's worth noting that modules are independent of the files the code blocks are contained in; although it would appear the only way to load a file blah.rs is to create a module called blah, you can use the #[path] to get around this, if you need to for some reason. Unfortunately, it doesn't appear to support wildcards, aggregating functions from multiple files into a top-level module is rather tedious.
I'm assuming you want to declare utils and utils::logging at the top level, and just wish to call functions from them inside module1::blah::blah2. The declaration of a module is done with mod, which inserts it into the AST and defines its canonical foo::bar::baz-style path, and normal interactions with a module (away from the declaration) are done with use.
// main.rs
mod utils {
pub mod logging { // could be placed in utils/logging.rs
pub fn trace(msg: &str) {
println!(": {}\n", msg);
}
}
}
mod module1 {
pub mod blah { // in module1/blah.rs
mod blah2 { // in module1/blah2.rs
// *** this line is the key, to bring utils into scope ***
use crate::utils;
pub fn doit() {
utils::logging::trace("Blah2 invoked");
}
}
pub fn doit() {
blah2::doit();
}
}
}
fn main() {
utils::logging::trace("Logging works");
module1::blah::doit();
}
The only change I made was the use crate::utils; line in blah2 (in Rust 2015 you could also use use utils or use ::utils). Also see the second half of this answer for more details on how use works. The relevant section of The Rust Programming Language is a reasonable reference too, in particular these two subsections:
Separating Modules into Different Files
Bringing Paths into Scope with the use Keyword
Also, notice that I write it all inline, placing the contents of foo/bar.rs in mod foo { mod bar { <contents> } } directly, changing this to mod foo { mod bar; } with the relevant file available should be identical.
(By the way, println(": {}\n", msg) prints two new lines; println! includes one already (the ln is "line"), either print!(": {}\n", msg) or println!(": {}", msg) print only one.)
It's not idiomatic to get the exact structure you want, you have to make one change to the location of blah2.rs:
src
├── main.rs
├── module1
│   ├── blah
│   │   └── blah2.rs
│   └── blah.rs
└── utils
└── logging.rs
main.rs
mod utils {
pub mod logging;
}
mod module1 {
pub mod blah;
}
fn main() {
utils::logging::trace("Logging works");
module1::blah::doit();
}
utils/logging.rs
pub fn trace(msg: &str) {
println!(": {}\n", msg);
}
module1/blah.rs
mod blah2;
pub fn doit() {
blah2::doit();
}
module1/blah/blah2.rs (the only file that requires any changes)
// this is the only change
// Rust 2015
// use utils;
// Rust 2018
use crate::utils;
pub fn doit() {
utils::logging::trace("Blah2 invoked");
}
I realize this is a very old post and probably wasn't using 2018. However, this can still be really tricky and I wanted to help those out that were looking.
Because Pictures are worth a thousand words I made this simple for code splitting.
Then as you probably guessed they all have an empty pub fn some_function().
We can further expand on this via the changes to main
The additional changes to nested_mod
Let's now go back and answer the question:
We added blah1 and blah2 to the mod_1
We added a utils with another mod logging inside it that calls some fn's.
Our mod_1/mod.rs now contains:
pub mod blah.rs
pub mod blah2.rs
We created a utils/mod.rs used in main containing:
pub mod logging
Then a directory called logging/with another mod.rs where we can put fns in logging to import.
Source also here https://github.com/DavidWhit/Rust_Modules
Also Check Chapters 7 for libs example and 14.3 that further expands splitting with workspaces in the Rust Book. Good Luck!
Answers here were unclear for me so I will put my two cents for future Rustaceans.
All you need to do is to declare all files via mod in src/main.rs (and fn main of course).
// src/main.rs
mod module1 {
pub mod blah;
pub mod blah2;
}
mod utils {
pub mod logging;
}
fn main () {
module1::blah::doit();
}
Make everything public with pub you need to use externally (copy-pasted original src/utils/logging.rs). And then simply use declared modules via crate::.
// src/module1/blah.rs
use crate::utils::logging;
// or `use crate::utils` and `utils::logging::("log")`, however you like
pub fn doit() {
logging::trace("Logging works");
}
p.s. I shuffled functions a bit for a cleaner answer.
If you create a file called mod.rs, rustc will look at it when importing a module. I would suggest that you create the file src/utils/mod.rs, and make its contents look something like this:
pub mod logging;
Then, in main.rs, add a statement like this:
use utils::logging;
and call it with
logging::trace(...);
or you could do
use utils::logging::trace;
...
trace(...);
Basically, declare your module in the mod.rs file, and use it in your source files.

How do I access exported functions inside a crate's "tests" directory?

How do I access my libraries exported functions inside the create's "tests" directory?
src/relations.rs:
#![crate_type = "lib"]
mod relations {
pub fn foo() {
println!("foo");
}
}
tests/test.rs:
use relations::foo;
#[test]
fn first() {
foo();
}
$ cargo test
Compiling relations v0.0.1 (file:///home/chris/github/relations)
/home/chris/github/relations/tests/test.rs:1:5: 1:14 error: unresolved import `relations::foo`. Maybe a missing `extern crate relations`?
/home/chris/github/relations/tests/test.rs:1 use relations::foo;
^~~~~~~~~
If I add the suggested extern crate relations, the error is:
/home/chris/github/relations/tests/test.rs:2:5: 2:19 error: unresolved import `relations::foo`. There is no `foo` in `relations`
/home/chris/github/relations/tests/test.rs:2 use relations::foo;
^~~~~~~~~~~~~~
I want to test my relations in this separate tests/test.rs file. How can I solve these use issues?
Your problem is that, first, mod relations is not public so it is not visible outside of the crate, and second, you don't import your crate in tests.
If you build your program with Cargo, then the crate name will be the one you defined in Cargo.toml. For example, if Cargo.toml looks like this:
[package]
name = "whatever"
authors = ["Chris"]
version = "0.0.1"
[lib]
name = "relations" # (1)
And src/lib.rs file contains this:
pub mod relations { // (2); note the pub modifier
pub fn foo() {
println!("foo");
}
}
Then you can write this in tests/test.rs:
extern crate relations; // corresponds to (1)
use relations::relations; // corresponds to (2)
#[test]
fn test() {
relations::foo();
}
The solution was to specify a crate_id at the top of src/relations.rs:
#![crate_id = "relations"]
#![crate_type = "lib"]
pub fn foo() {
println!("foo");
}
This seems to declare that all the contained code is part of a "relations" module, though I'm still not sure how this is different to the earlier mod block.

Deriving Encodable trait in a module not working

I have a main.rs file and a logging module inside logging.rs file. My file layout is:
.
├── Cargo.toml
├── src
│ ├── logging.rs
│ └── main.rs
The contents of my main.rs
mod logging;
fn main(){}
The contents of logging.rs
extern crate serialize;
use self::serialize::{json, Encoder, Encodable};
#[deriving(Encodable)]
pub struct Person {
pub age: i32
}
However this does not compile. The error is:
error: failed to resolve. Did you mean `self::serialize`?
/Users/valentin/../src/logging.rs:7 #[deriving(Encodable)]
Three questions:
Why does not it compile?
Why does moving the struct and use directive to main.rs makes it compile?
Why does changing serialize::Encodable to Show trait makes it compile even inside logging module?
However
If I add
extern crate serialize;
use self::serialize::{json, Encoder, Encodable};
to main.rs, it all starts compiling.
This is very confusing, the fourth questions is why isn't it sufficient to have only one extern crate + use serialize::.. inside logging module?
Let’s look at the code that’s generated, with rustc main.rs --pretty expanded:
#![feature(phase)]
#![no_std]
#![feature(globs)]
#[phase(plugin, link)]
extern crate std = "std";
extern crate rt = "native";
use std::prelude::*;
mod logging {
extern crate serialize;
use std::prelude::*;
use self::serialize::{json, Encoder, Encodable};
pub struct Person {
pub age: i32,
}
#[automatically_derived]
impl <__S: ::serialize::Encoder<__E>, __E>
::serialize::Encodable<__S, __E> for Person {
fn encode(&self, __arg_0: &mut __S) ->
::std::result::Result<(), __E> {
match *self {
Person { age: ref __self_0_0 } =>
__arg_0.emit_struct("Person", 1u, |_e| {
return _e.emit_struct_field("age", 0u,
|_e|
(*__self_0_0).encode(_e));
}),
}
}
}
}
fn main() { }
This demonstrates that the #[deriving(Encodable)]expands to stuff involving the paths ::serialize::*; that is, the item serialize from the crate root.
Now, extern crate serialize; from inside mod logging means that the path to serialize is ::logging::serialize, which is also accessible as self::serialize inside the module; there is no ::serialize.
The solution is moving the extern crate serialize; into the crate root. (This is where all extern crate definitions should be.) This is what fixed it for you, not the use self::serialize::{json, Encoder, Encodable};.

Resources