How do I refer to code in main.rs from tests? [duplicate] - rust

When creating a project with a test like so:
cargo init --bin projectname
mkdir projectname/tests
echo "extern crate projectname;" > projectname/tests/test.rs
cd projectname/
cargo build
I get this error when testing:
cargo test
Compiling projectname v0.1.0 (file:///home/username/Lab/projectname)
error[E0463]: can't find crate for `projectname`
--> tests/test.rs:1:1
|
1 | extern crate projectname;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate
How can I access the functions in ´projectname/src/main.rs´ from projectname/tests/test.rs?

How can I access functions in ´projectname/src/main.rs´ from projectname/tests/test.rs?
You cannot.
A binary cannot be used a an external crate (the same way as you can't use a ELF binary as a shared object/library)
You just have to change your initialisation to
cargo init --lib projectname
or rename your main.rs to lib.rs
If you really want to stick with a main, you may look at Rust package with both a library and a binary?.

Related

How to use my library from different project in rust [duplicate]

I've made a library:
cargo new my_lib
and I want to use that library in a different program:
cargo new my_program --bin
extern crate my_lib;
fn main {
println!("Hello, World!");
}
what do I need to do to get this to work?
They aren't in the same project folder.
.
├── my_lib
└── my_program
Hopefully this makes sense.
I thought I'd be able to override the path as per the Cargo guide, but it states
You cannot use this feature to tell Cargo how to find local unpublished crates.
This is when using the latest stable version of Rust (1.3).
Add a dependency section to your executable's Cargo.toml and specify the path:
[dependencies.my_lib]
path = "../my_lib"
or the equivalent alternate TOML:
[dependencies]
my_lib = { path = "../my_lib" }
Check out the Cargo docs for specifying dependencies for more detail, like how to use a git repository instead of a local path.
I was looking for an equivalent to mvn install. While this question is not quite a duplicate of my original question, anyone who stumbles across my original question and follows the link here will find a more complete answer.
The answer is "there is no equivalent to mvn install because you have to hard-code the path in the Cargo.toml file which will probably be wrong on someone else's computer, but you can get pretty close."
The existing answer is a bit brief and I had to flail around for a bit longer to actually get things working, so here's more detail:
/usr/bin/cargo run --color=always --package re5 --bin re5
Compiling re5 v0.1.0 (file:///home/thoth/art/2019/radial-embroidery/re5)
error[E0432]: unresolved import `embroidery_stitcher`
--> re5/src/main.rs:5:5
|
5 | use embroidery_stitcher;
| ^^^^^^^^^^^^^^^^^^^ no `embroidery_stitcher` in the root
rustc --explain E0432 includes this paragraph that echos Shepmaster's answer:
Or, if you tried to use a module from an external crate, you may have missed
the extern crate declaration (which is usually placed in the crate root):
extern crate core; // Required to use the `core` crate
use core::any;
Switching from use to extern crate got me this:
/usr/bin/cargo run --color=always --package re5 --bin re5
Compiling embroidery_stitcher v0.1.0 (file:///home/thoth/art/2019/radial-embroidery/embroidery_stitcher)
warning: function is never used: `svg_header`
--> embroidery_stitcher/src/lib.rs:2:1
|
2 | fn svg_header(w: i32, h: i32) -> String
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(dead_code)] on by default
Compiling re5 v0.1.0 (file:///home/thoth/art/2019/radial-embroidery/re5)
error[E0603]: function `svg_header` is private
--> re5/src/main.rs:8:19
|
8 | let mut svg = embroidery_stitcher::svg_header(100,100);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I had to slap a pub on the front of that function
pub fn svg_header(w: i32, h: i32) -> String
Now it works.

UseDeclaration cannot find struct in the crate root

I start with the cargo new tst. Then in the src/lib.rs I have:
pub struct Config {}
And src/main.rs looks like the following:
use crate::Config;
fn main() {}
This however does not compile:
> cargo run
Compiling tst v0.1.0 (/home/*/rust/book/tst)
error[E0432]: unresolved import `crate::Config`
--> src/main.rs:1:5
|
1 | use crate::Config;
| ^^^^^^^^^^^^^ no `Config` in the root
For more information about this error, try `rustc --explain E0432`.
error: could not compile `tst` due to previous error
But if I replace crate:: with the name of the crate like so:
use tst::Config;
fn main() {}
Then it just work:
> cargo run
Compiling tst v0.1.0 (/home/*/rust/book/tst)
warning: unused import: `tst::Config`
--> src/main.rs:1:5
|
1 | use tst::Config;
| ^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
warning: `tst` (bin "tst") generated 1 warning
Finished dev [unoptimized + debuginfo] target(s) in 0.25s
Running `target/debug/tst`
The output for rustc --explain E0432 has the following quote, which if I understand it correctly means, that I can either use the name of a crate or simply crate:::
In Rust 2018, paths in use statements are relative to the current module
unless they begin with the name of a crate or a literal crate::, in which
case they start from the crate root. As in Rust 2015 code, the self:: and
super:: prefixes refer to the current and parent modules respectively.
Am I doing something wrong in here? Is there a way to use code from lib.rs without hardcoding the name of the crate?
> rustc --version
rustc 1.56.1 (Arch Linux rust 1:1.56.1-3)
> cat Cargo.toml
[package]
name = "tst"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
There is no way to refer to “the library crate in my package”; you must refer to it by its name. The Rust compiler doesn't (currently) know anything about other crates that happen to be in the same Cargo package; it just compiles one crate at a time.
In order for this to change, you would need to write a Rust RFC, which would need to include a description of why it would be valuable to have this feature — probably a stronger argument than “it would be less hardcoded”, since main depending on the library is almost certainly going to use library-specific names anyway, so the name of the library itself is a minor issue (unless, I suppose, you're creating many packages from a common template).

Why do I get "can't find crate" that is listed as a dependency in Cargo.toml when I compile with rustc?

My Cargo.toml includes this:
[dependencies]
chrono = "0.4"
And my code includes this:
extern crate chrono;
use chrono::{Duration, DateTime, Utc};
yet when I run my code, I get this error:
error[E0463]: can't find crate for `chrono`
--> src/lib.rs:1:1
|
1 | extern crate chrono;
| ^^^^^^^^^^^^^^^^^^^^ can't find crate
I am working on an Exercism exercise, so the way I am building/running the program is rustc src/lib.rs to test my solution. Is the problem because I'm not running rustc src/main.rs?
When you're directly running rustc, all that compiler knows is the command line arguments. It doesn't know anything about Cargo.toml, in particular, and so it doesn't know where to look for chrono library.
To use dependency management, you have to compile your project with Cargo - just use cargo build/cargo run/cargo test, and everything should be fine. See the Book for details.
If, however, you want (for some reason) use rustc directly, I'd advise to check first cargo anyway, by using cargo build --verbose. It will show all the commands that are invoked, allowing you to inspect the possible arguments to be defined manually.

What is the Rust/Cargo equivalent of `mvn install` for a personal library not uploaded to crates.io? [duplicate]

I've made a library:
cargo new my_lib
and I want to use that library in a different program:
cargo new my_program --bin
extern crate my_lib;
fn main {
println!("Hello, World!");
}
what do I need to do to get this to work?
They aren't in the same project folder.
.
├── my_lib
└── my_program
Hopefully this makes sense.
I thought I'd be able to override the path as per the Cargo guide, but it states
You cannot use this feature to tell Cargo how to find local unpublished crates.
This is when using the latest stable version of Rust (1.3).
Add a dependency section to your executable's Cargo.toml and specify the path:
[dependencies.my_lib]
path = "../my_lib"
or the equivalent alternate TOML:
[dependencies]
my_lib = { path = "../my_lib" }
Check out the Cargo docs for specifying dependencies for more detail, like how to use a git repository instead of a local path.
I was looking for an equivalent to mvn install. While this question is not quite a duplicate of my original question, anyone who stumbles across my original question and follows the link here will find a more complete answer.
The answer is "there is no equivalent to mvn install because you have to hard-code the path in the Cargo.toml file which will probably be wrong on someone else's computer, but you can get pretty close."
The existing answer is a bit brief and I had to flail around for a bit longer to actually get things working, so here's more detail:
/usr/bin/cargo run --color=always --package re5 --bin re5
Compiling re5 v0.1.0 (file:///home/thoth/art/2019/radial-embroidery/re5)
error[E0432]: unresolved import `embroidery_stitcher`
--> re5/src/main.rs:5:5
|
5 | use embroidery_stitcher;
| ^^^^^^^^^^^^^^^^^^^ no `embroidery_stitcher` in the root
rustc --explain E0432 includes this paragraph that echos Shepmaster's answer:
Or, if you tried to use a module from an external crate, you may have missed
the extern crate declaration (which is usually placed in the crate root):
extern crate core; // Required to use the `core` crate
use core::any;
Switching from use to extern crate got me this:
/usr/bin/cargo run --color=always --package re5 --bin re5
Compiling embroidery_stitcher v0.1.0 (file:///home/thoth/art/2019/radial-embroidery/embroidery_stitcher)
warning: function is never used: `svg_header`
--> embroidery_stitcher/src/lib.rs:2:1
|
2 | fn svg_header(w: i32, h: i32) -> String
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(dead_code)] on by default
Compiling re5 v0.1.0 (file:///home/thoth/art/2019/radial-embroidery/re5)
error[E0603]: function `svg_header` is private
--> re5/src/main.rs:8:19
|
8 | let mut svg = embroidery_stitcher::svg_header(100,100);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I had to slap a pub on the front of that function
pub fn svg_header(w: i32, h: i32) -> String
Now it works.

How to use a local unpublished crate?

I've made a library:
cargo new my_lib
and I want to use that library in a different program:
cargo new my_program --bin
extern crate my_lib;
fn main {
println!("Hello, World!");
}
what do I need to do to get this to work?
They aren't in the same project folder.
.
├── my_lib
└── my_program
Hopefully this makes sense.
I thought I'd be able to override the path as per the Cargo guide, but it states
You cannot use this feature to tell Cargo how to find local unpublished crates.
This is when using the latest stable version of Rust (1.3).
Add a dependency section to your executable's Cargo.toml and specify the path:
[dependencies.my_lib]
path = "../my_lib"
or the equivalent alternate TOML:
[dependencies]
my_lib = { path = "../my_lib" }
Check out the Cargo docs for specifying dependencies for more detail, like how to use a git repository instead of a local path.
I was looking for an equivalent to mvn install. While this question is not quite a duplicate of my original question, anyone who stumbles across my original question and follows the link here will find a more complete answer.
The answer is "there is no equivalent to mvn install because you have to hard-code the path in the Cargo.toml file which will probably be wrong on someone else's computer, but you can get pretty close."
The existing answer is a bit brief and I had to flail around for a bit longer to actually get things working, so here's more detail:
/usr/bin/cargo run --color=always --package re5 --bin re5
Compiling re5 v0.1.0 (file:///home/thoth/art/2019/radial-embroidery/re5)
error[E0432]: unresolved import `embroidery_stitcher`
--> re5/src/main.rs:5:5
|
5 | use embroidery_stitcher;
| ^^^^^^^^^^^^^^^^^^^ no `embroidery_stitcher` in the root
rustc --explain E0432 includes this paragraph that echos Shepmaster's answer:
Or, if you tried to use a module from an external crate, you may have missed
the extern crate declaration (which is usually placed in the crate root):
extern crate core; // Required to use the `core` crate
use core::any;
Switching from use to extern crate got me this:
/usr/bin/cargo run --color=always --package re5 --bin re5
Compiling embroidery_stitcher v0.1.0 (file:///home/thoth/art/2019/radial-embroidery/embroidery_stitcher)
warning: function is never used: `svg_header`
--> embroidery_stitcher/src/lib.rs:2:1
|
2 | fn svg_header(w: i32, h: i32) -> String
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(dead_code)] on by default
Compiling re5 v0.1.0 (file:///home/thoth/art/2019/radial-embroidery/re5)
error[E0603]: function `svg_header` is private
--> re5/src/main.rs:8:19
|
8 | let mut svg = embroidery_stitcher::svg_header(100,100);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I had to slap a pub on the front of that function
pub fn svg_header(w: i32, h: i32) -> String
Now it works.

Resources