Main Question
How to use code from helper1.rs in main.rs.
// main.rs
mod lib;
use lib::lib_function;
use lib::public_library;
mod module_a;
mod module_b;
use module_a::{helper1::helper1_function, mod_a_function};
use module_b::{helper2, helper3, mod_b_function};
fn main() {
println!("Hello, world from main!");
lib_function();
public_library::public_library_mod_function();
helper1_function();
mod_a_function();
helper2::helper2_function();
helper3::helper3_function();
mod_b_function();
}
// module_b/mod.rs
pub mod helper2;
pub mod helper3;
pub fn mod_a_function() {
println!("Printing from module_b/mod.rs");
}
// module_b/helper2.rs
pub fn helper2_function() {
println!("Hello from Helper 2!!");
}
I get the error:
error: couldn't read src\module_b\mod.rs: stream did not contain valid UTF-8
--> src\main.rs:14:1
|
14 | mod module_b;
| ^^^^^^^^^^^^^
error: could not compile `rust_modules_cheat_sheet` due to previous error
I'm not sure what non-utf-8 character is in module_b but isn't in module_a.
Cheat Sheet for modules and importing in Rust
I've seen a lot of tutorials online that kind of say the same thing, but it's not complete or sophisticated for other cases. I wanted to ask the community as well as research how to use code from various situations and modules in rust. If you would like to comment below for the two cases I am unsure of right now, that would be appreciated.
Example Directory
/src
| main.rs
| lib.rs
| other.rs
|- module_a/
| | mod.rs
| | helper1.rs
|- module_b/
| | mod.rs
| | helper2.rs
| | helper3.rs
Various Situation
Using code from other.rs in main.rs (Understood)
Using code from lib.rs in main.rs (Understood)
Using code from mod.rs in lib.rs (Understood)
Using code from helper1.rs in main.rs (Understood)
Using code from helper2.rs in helper3.rs (Unsure)
Using code from module_a/mod.rs in module_b/mod.rs (use crate::module_a)
Github Repo for Future Reference
Link to repo
Hopefully, this helps others in the future. I know I need it.
Thanks
This is not from a misunderstanding of Rust's module system. Your module_b\mod.rs file is UTF-16 encoded instead of UTF-8 encoded as Rust is expecting.
If you're using VS Code: Change the encoding of a file in Visual Studio Code You can change the encoding by clicking on the UTF-16 LE part of the bottom status bar and selecting Save with encoding and then selecting UTF-8.
If using Vim: How can I change a file's encoding with vim?
Related
I have a Rust project consisting of two binary sources sharing the same library:
Cargo.toml:
<...>
[[bin]]
name = "quoter_xml"
path = "src/quoter_xml.rs"
[[bin]]
name = "quoter"
path = "src/quoter.rs"
<...>
src/quoter_xml.rs:
use <...>
fn main() {
<...>
}
src/quoter.rs:
use <...>
fn main() {
<...>
}
src/lib.rs:
pub mod <...>
When I compile it, I get two binaries: quoter_xml and quoter_xml.
When I generate doc using cargo doc, I get independent doc files doc/quoter_xml/index.html and doc/quoter/index.html.
What I want is to add some description texts to the top of these doc files.
I've tried to add "//!"-type comments to binary sources, for example:
src/quoter_xml.rs:
use <...>
//! quoter_xml - this binary is for <..>
fn main() {
<...>
}
But if I compile project after it, I get an error:
error[E0753]: expected outer doc comment
--> src/quoter_xml.rs:10:1
|
10 | //! quoter_xml - this binary is for <..>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: inner doc comments like this (starting with `//!` or `/*!`) can only appear before items
help: you might have meant to write a regular comment
|
10 - //! quoter_xml - this binary is for <..>
10 + // quoter_xml - this binary is for <..>
|
Compiler consider to use regular comments, but I don't want it: I need comments that will get to the top of doc pages, "//!"-type comments.
I've search Internet and found recommendation to place these type of comments in src/lib.rs file, but this is not what I want. I want to have independent top-level comments in doc for each binary file.
Any suggestion?
I believe you simply need to move your comment above the use statement in quoter_xml.rs.
//! quoter_xml - this binary is for <..>
use <...>
// Crate level doc comment cannot be after any code.
fn main() {
<...>
}
I have a Cargo project set up with a library and a binary. The library is meant to be used on many platforms, including Android, while the binary is only meant to be used on Linux. As such, the binary contains a bunch of Linux-specific code that does not compile when I target Android. Is there a way to specify (without using features) that the binary should only be compiled on Linux?
I tried putting #![cfg(target_os = "linux")] in the main.rs of my binary, but then I got this error:
error[E0601]: `main` function not found in crate `server`
--> src/bin/server/main.rs:1:1
|
1 | / #![cfg(target_os = "linux")]
2 | |
3 | | use anyhow::{self, Context};
4 | |
... |
36 | | }
37 | | }
| |_^ consider adding a `main` function to `src/bin/server/main.rs`
I had exactly the same problem. The official Rust docs do not seem to mention how to solve it. But I found a solution.
The trick is to specify two main() functions in the file main.rs. The first one contains the code you want to execute when you are on Linux. The second one remains empty. With the help of conditional compilation, you tell the compiler which of the two main() functions to compile.
// within main.rs
#[cfg(target_os = "linux")]
fn main() {
// Your Linux-specific code goes here...
}
#[cfg(not(target_os = "linux"))]
fn main() {} // remains empty for all other OS
If you have OS-specific imports or other code at the top-level, just wrap it inside a module and use conditional compilation for it as well.
#[cfg(target_os = "linux")]
mod linux {
use anyhow::{self, Context};
// ...
}
The below link has related information that should help you in terms of target selection and selective compilation https://doc.rust-lang.org/cargo/commands/cargo-build.html#target-selection
I am trying to build a single Rust binary executable. In the src directory I have four files:
main.rs:
use fasta_multiple_cmp::get_filenames;
fn main() {
get_filenames();
}
mod.rs:
pub mod fasta_multiple_cmp;
pub mod build_sequences_matrix;
fasta_multiple_cmp.rs:
pub mod fasta_multiple_cmp {
...
pub fn get_filenames() {
let args: Vec<String> = env::args().collect();
...
build_sequences_matrix.rs:
pub mod build_sequences_matrix {
use simple_matrix::Matrix;
...
Cargo told me:
src/main.rs:3:5
|
3 | use fasta_multiple_cmp::get_filenames;
| ^^^^^^^^^^^^^^^^^^ use of undeclared crate or module `fasta_multiple_cmp
I believed I understood some little things, but ther I'm lost. What is going on?
Thaks for any hint!
Your original code wasn't working because Rust's use is looking for a crate to import from, not just a file in the same directory.
If you want to separate logic into other files, you will need to break apart your project into both a binary and into a library (aka - a crate that your binary can use for imports).
This can be done in your Cargo.toml as:
[package]
edition = "2018"
name = "my_project"
version = "1.2.3"
... your other settings ...
[[bin]]
edition = "2018"
name = "whatever_name_for_binary"
path = "src/main.rs"
This means that your binary will be compiled into a file called "whatever_name_for_binary" in your target folder. It also means your non-binary files act as a library, and can be imported by your binary by using use my_project::some_module;
Because your project will now contain both a library and binary, you will need to specify when you want to run/compile the binary.
You do this by running: cargo run --bin whatever_name_for_binary
For more information, see the Rust Book's Chapter on Modules.
This question already has answers here:
How do I import from a sibling module?
(1 answer)
How to use one module from another module in a Rust cargo project?
(3 answers)
Split a module across several files
(7 answers)
Closed 2 years ago.
Welcome, this question is for sure repeated, but for past 2 hours my mod didn't work and im sure I've done everything correctly.
Here is my tree:
project \
|- target...
|
|- rust_stuff...
|
\- src
|- main.rs
|
|- first_file.rs
|
\- second_file.rs
And here is second one, for reference when i will list what i tried:
project \
|- target...
|
|- rust_stuff...
|
\- src
|- main.rs
|
|- first_file.rs
|
\- cool_folder
|
\second_file.rs
Ok, so we have:
// -- MAIN --
mod first_file;
pub use first_file::*;
fn main() {
call_first();
}
Now, first_file.rs contains
// -- FIRST_FILE --
mod second_file; //E: Not found
pub use second_file; //E: Not used
pub fn call_first(){
call_second(); //E: Out of scope
}
I will stop here, second_file exists, and cannot be accesed by first_file but can be accessed by main just like this:
// -- MAIN --
mod first_file;
pub use first_file::*;
mod second_file;
pub use second_file::*;
fn main() {
call_first(); //Would call 'call_second' but as i presented it can't
call_second(); //Returns "Hello world" in terminal
}
(Thats assuming second_file is same as first_file with just different function naming)
Now, reffering to second tree i showed, i tried putting those files in cool_file, but it worked out the same except i used:
mod cool_file; //Err
pub use cool_file::*;
// this does not work
pub use second_file::*;
// neither does this
In documentation from what i understand, i wrote it the right way, in regards to first example, i have no idea what to do. Please help.
RFC 1358 suggested an alignment attribute #[repr(align="N")] and it was accepted. Rust issue 33626 incorporated the feature into the nightly version.
I'm unable to use this feature with rustc 1.19.0-nightly (777ee2079 2017-05-01). If I compile without the feature gate (#![feature(repr_align)]):
#[repr(align="16")]
struct Foo {
bar: u32,
}
I get the following error statement:
error: the struct `#[repr(align(u16))]` attribute is experimental (see issue #33626)
--> foo.rs:3:1
|
3 | / struct Foo {
4 | | bar: u32,
5 | | }
| |_^
|
= help: add #![feature(repr_align)] to the crate attributes to enable
When I compile with the feature gate, the error message says:
error[E0552]: unrecognized representation hint
--> foo.rs:3:8
|
3 | #[repr(align="16")]
| ^^^^^^^^^^
I also tried the version suggested by the first error message (even though it does not comply with the issue), but still without success. What is the correct way to use the alignment feature?
You can make that feature work when combined with
attribute literals (Playground):
#![feature(repr_align)]
#![feature(attr_literals)]
#[repr(align(16))]
struct Foo {
bar: u32,
}
This is known to work in the latest development version (PR #41673). Searching "repr align" in the Rust compiler's codebase,
all occurrences rely on attribute literals, so it seems likely that the documented form repr(align="N") is not yet supported.