run specific .rs file - rust

quick introduction, I came from python I have studied it by myself, and now I'm trying to learn Rust. I find it a bit confusing.
I have a main.rs file and other .rs files in the src directory just to have cleaner and organized code, as each of these other files do specific tasks and the main.rs just put all together with a simple CLI.
I just wanna test a single of these .rs file, or even a single fn inside to check if the result is what I am expecting.
How can I do that? It's simple, it's stupid, but I have read around and found nothing that could help me in the end.
I read this, where it talks about making a tests folder and then using cargo test, I've done it, but it still runs the src/main.rs instead of what I have put in tests. BTW I'm using CLion with the Rust plugin.
Sorry if this is somewhat a duplicate, I looked around but I didn't found an answer.

This funcitonality is not really part of Rust itself, but there are some crates that do it. The one I'm most familiar with is rust-script. It works with a hashbang like #!/usr/bin/env rust-script at the top of your script, then run it with ./script.rs. You can even specify dependencies in the script which get parsed out of some special comments.
Edit: Sorry yes - it looks like you're trying to write/run tests. The page you linked in the book should cover what you're trying to do. I'm not sure what you mean by "it still runs the src/main.rs instead of what I have put in tests". Do you have mod tests in main.rs as well?

you can compile any .rs file using rustc your_file.rs command as long as the file contains main() function. rustc will fail if there isn't main function:
error[E0601]: `main` function not found in crate `abc`
--> abc.rs:5:2
|
5 | }
| ^ consider adding a `main` function to `abc.rs`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0601`.
but you can skip this by marking the file as library crate instead of bin:
rustc you_file.rs --crate-type=lib

Related

Rust: Cannot access functions in subdirectories [duplicate]

This question already has an answer here:
Can't understand Rust module system
(1 answer)
Closed 2 years ago.
I am learning rust and am going through the book and have run into a question. Is it possible to access files within a folder? I am currently having issues with this.
Here is a project which demonstrates the issue: https://github.com/joemspalding/rust-stack-overflow-file-example/tree/master/src
In this project, I can successfully import functions from a different file, however, trying to access a file from a different folder is where I lose understanding syntactically. I feel I've tried nearly every combination of
mod foo;
mod foo::bar;
use foo;
use foo::bar;
Currently, running cargo run produces the following compile time error
Compiling my-project v0.1.0 (J:\Projects\rust\the_book\ch7\my-project)
error[E0432]: unresolved import `foo`
--> src\main.rs:1:5
|
1 | use foo::bar;
| ^^^ use of undeclared type or module `foo`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0432`.
error: could not compile `my-project`.
To learn more, run the command again with --verbose.
I've been reading into this for hours and all of the resources I can find have great examples of reading code from a file on the same level, but not on reading code through folders.
Another common line I've seen is with the use of folder/mod.rs This seems unstylistic of rust after an update in 2018 and I'd like to avoid it if possible.
You must use mod.rs. It is the preferred option in rust 2018 and above. Module definitions aren't file paths and shouldn't be treated as such. Think of them more as C++ namespaces.
You could also choose to rename your mod.rs to match the name of the folder it is in (Ex: example_a/mod.rs -> example_a/example_a.rs). However I almost never this done and I find its much easier to navigate code with mod.rs.
If your mod.rs doesn't have any useful code, maybe you don't need a submodule.
A mod.rs should have code which relates to its sub modules. If it is only a couple lines long, you may want to skip adding the folder entirely since it doesn't sound like it has any purpose in your specific use case. This isn't like the empty __init__.py files of python 2.

Conditional compilation for Rust build.rs script?

The Rust language supports conditional compilation using attributes like #[cfg(test)].
Rust also supports build scripts using a build.rs file to run code as part of the build process to prepare for compilation.
I would like to use conditional compilation in Rust code to conditionally compile depending on whether we're compiling for a build script, similar to how that is possible for test builds.
Imagine the following:
#[cfg(build)]
fn main() {
// Part of build script
}
#[cfg(not(build))]
fn main() {
// Not part of build script, probably regular build
}
This does not work, because build is not a valid identifier here.
Is it possible to do this using a different attribute, or could some other trick be used to achieve something similar?
For some context on this issue:
My goal is to generate shell completion scripts through clap at compile time. I've quite a comprehensive App definition across multiple files in the application. I'd like to use this in build.rs by including these parts using the include!(...) macro (as suggested by clap), so I don't have to define App a second time. This pulls some dependencies with it, which I'd like to exclude when used by the build.rs file as they aren't needed in that case. This is what I'm trying to make available in my build.rs script.
You can just put the build code in build.rs (or presumably have build.rs declare a mod xyz to pull in another file).
I wonder if the question you are trying to ask is whether you can reference the same code from build.rs and main.rs, and if so can that code tell if it's being called by one or the other. It seems you could switch on an environment variable set when using build.rs (using something like option_env, but possibly a nicer way might be to enable a feature in the main code from within build.rs.
(Have a read of the documentation for build scripts if you haven't already.)
This is what works for me:
fn main() {
if std::env::var("PROFILE").unwrap() == "debug" {
// Here I do something that is needed for tests
// only, not for 'release'
}
}

What is a Rust systest?

I sometimes see that a Rust crate has a folder called systest. I guess that the name stands for "system test", but I can't find any documentation of this.
My questions are:
What is the purpose of a systest? Just testing that a crate compiles fine, or also testing that some code in another crate runs fine?
What are the rules to follow when writing a systest? Is it just a crate in a folder called systest?
Why does the lib.rs in systest/src seem to always include a file all.rs generated from build.rs?
systest is not a standard name used in Rust or Cargo. However, it is the name suggested by the documentation for ctest, which performs automated testing for FFI bindings. build.rs uses ctest to generate the all.rs file which contains the tests, and this is included from the main file.
According to the documentation, the tests generate include ensuring that all function signatures, constant values, struct layout/alignment, type size/alignment, etc., all match their C equivalent.

"cargo check" gives dead code warning for function used only by test [duplicate]

I'm writing a program in Rust and I have some tests for it. I wrote a helper function for these tests, but whenever I build using cargo build it warns me that the function is never used:
warning: function is never used: ... #[warn(dead_code)] on by default
How I can mark this function as used so as not to get the warnings?
Specific question
How I can mark this function as used so as not to get the warnings?
The Rust compiler runs many lints to warn you about possible issues in your code and the dead_code lint is one of them. It can be very useful in pointing out mistakes when code is complete, but may also be a nuisance at earlier stages. Often, this can be solved by either deleting unused code, or by marking a public method. However, all lints can be turned off by allowing them, and your error message (#[warn(dead_code)] on by default) contains the name of the lint you could disable.
#[allow(dead_code)]
fn my_unused_function() {}
Alternative for testing
I wrote a helper function for these tests, but whenever I build using cargo build it warns me that the function is never used.
This happens to be a special case, which is that code that is only used for testing isn't needed in the real executable and should probably not be included.
In order to optionally disable compilation of test code, you can mark it accordingly using the cfg attribute with the test profile.
#[cfg(test)]
fn my_test_specific_function() {}
When marked in this way, the compiler knows to ignore the method during compilation. This is similar to commonly used ifdef usage in other languages like C or C++, where you are telling a preprocessor to ignore the enclosed code unless TESTING is defined.
#ifdef TESTING
...
#endif
For people getting this warning while making a rust library, you may get this if you don't have your modules set to pub in your lib.rs.
pub mod foo;
If something is only used in tests, it should be omitted altogether. This can be done with the #[cfg(test)] attribute.
dead_code is a lint, which means you can allow it on the thing that's causing it to trigger.
#[allow(dead_code)]
fn dummy() {}
fn main() {}
There is another situation where this can occur. If you have several helper functions in a module, e.g. in tests/utils/mod.rs and then several integration tests (tests/a.rs, tests/b.rs) each of which does
mod utils;
use utils::...;
then you will get dead code warnings if you do not use all of the code from all of the tests. For example if test a.rs only uses utils::foo and b.rs only uses utils::bar then you will get dead code warnings for both.
That is because each test is compiled as an independent crate. Here is the bug report for it. It looks difficult to solve so I wouldn't hold my breath.
You can disable specific lints for a whole project in Rust by going into your main.rs file and adding the following at the very top of the file:
#![allow(
dead_code,
unused_imports
)]
You max prefix the unused function name with an underscore:
fn _dummy() {}
fn main() {}
See: https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#dead-code
For some reason I found that setting the main function to public:
pub fn main()
and then copying my main.rs file to lib.rs
cp src/main.rs src/lib.rs
then recompiling fixed this.
No need to use a macro for it, although the macro should work for non main functions.

Multiple Rust source files for cargo

If I have multiple .rs files in the src directory of a Cargo package, what are the rules for visibility, importing, etc.?
Currently, any extra (i.e. not the file that is explicitly identified as the source for the executable in Cargo.toml) files are ignored.
What do I need to do to fix this?
There is nothing special about Cargo at all in this way. It’s all the perfectly normal Rust module system. If Cargo will be compiling src/lib.rs, that’s more or less equivalent to having executed rustc --crate-type lib src/lib.rs (there are more command line arguments in practice, but that’s the basics of it).
Other files are then used with mod, use and so forth. Files are not automatically imported or anything like that. This part is not documented very clearly yet; a couple of things that show briefly how to achieve things are http://rustbyexample.com/mod/split.html and http://doc.rust-lang.org/reference.html#modules, but any non-trivial code base will use them and so you can pick just about any code base to look at for examples.
It's hard to say what you're getting tripped up on from the info you shared. Here are three seemingly trivial things that I still had to refer to the documentaton to figure out:
First of all,
mod foo;
looks like a declaration, but it without arguments it is actually something like an include. So you use the same keyword both for declaring and including modules, i.e. there is no using:: keyword.
Second, modules themselves can be public or private. If you didn't add a pub keyword both on the function in question AND on the containing module, that may be tripping you up.
pub mod foo {pub fn bar();}
Third, there seems to be an implicit module added at the top of every file. This is confusing; the reference manual talks about a strict separation between file paths and names, and the module paths in your code, but that abstraction seems to be leaky here.
Note, Rust is still pre-1.0 (0.12) at the time of writing, at the module system and file paths are relatively high level, so don't be surprised if what I said may already wrong by the time you read this.
Files are implicitly included from your rust code.
For instance, if a file src/foo.rs pointed by path in a [lib] or [[bin]] section of your Cargo.toml contains:
mod bar;
It tells cargo to build src/bar.rs too, and include it.

Resources