Reputation: 1562
I have read Managing Growing Projects with Packages, Crates, and Modules, but I still don't really understand the hierarchy. I know what is crate and that there should be at least one crate in package: max 1 library crate and 0 or more binary crates.
First: Assume I want to have both lib.rs
and main.rs
crates in package. How do I access/call functions from lib.rs
in main.rs
?
Second: when I create new library with cargo new --lib library-name
it creates directory with that name and bunch of files there, the only way I figured out to call functions from that library in src/main.rs
is:
mod some_library;
use crate::library_name::library_name::foo;
fn main() {
foo();
}
// Filename: src/library_name.rs
pub mod library_name; // I don't really understand this
// Filename: src/library_name/library_name.rs
pub fn foo() {
// ...
}
where I have the following hierarchy:
- package_name
- src
- library_name
- src
- lib.rs
- Cargo.toml
- library_name.rs
- library_name.rs
- main.rs
- Cargo.toml
Is it necessary for src/library_name.rs
to have the same name as src/library_name
library? I'm really confused.
Upvotes: 7
Views: 3935
Reputation: 28727
It's a hierarchy of three or four levels.
Workspace (optional): At the top there's the workspace. A workspace consists of one or more packages. The Cargo.toml
file is special and more or less only lists the workspace members.
Workspaces are optional and used for big projects. Smaller projects with only one package don't need them. In such cases we can ignore workspaces. We have a package at the top and the hierarchy is only three levels deep.
Package: Then there's the package. A package is what haves a real Cargo.toml
file. A package can compile to crates.
Crate: A crate is a library or an executable compiled from the package. A library crate has a lib.rs
file as a starting point. An executable crate has a main
function as a starting point. A package can compile to at most one library and several executables.
Module: Then there are modules. Modules are the hierarchical way how Rust organizes items like struct
, enum
, functions and others in the source code.
And how to you use this to give items unique names?
Answer: A fully qualified name starts with the package, then a series of module names then finally the item's name.
An example:
serde::de::value::StringDeserializer
(see here) has as package serde
, as module path de
then value
then the struct
is called StringDeserializer
.
And where's the crate?
The package serde
has only one crate, the library. If you look at the package's Cargo.toml
there are no binaries listed.
(People tend to be confused about packages and crates. Even sometimes I am not precise and say "the serde crate" when I mean the package.)
In short: A package is code under a name (for example serde
). A crate is a library or an executable.
Upvotes: 7