Skip to content

Latest commit

 

History

History
63 lines (38 loc) · 3.27 KB

split-out-code-to-a-library.md

File metadata and controls

63 lines (38 loc) · 3.27 KB
title timestamp author published description tags todo
How to refer to code that was split out to a library in Rust?
2023-08-31 09:30:01 -0700
szabgab
true
How to make sure the code of a crate does not need to be changed when the crate is renamed.
cargo
pub
crate
mod
What happens if we have such crate that uses the real name of the crate, but the user uses an alias when importing?

When you create a crate that needs to be executable, you use cargo new NAME that will automatically create a file called src/main.rs with a single main function.

In this file I created a new function called hello_in_main_rs and called it from the main function. Creating function in the main.rs file and calling it is the most simple.

{% include file="examples/split-out-code-to-a-library/src/main.rs" %}

lib.rs

In crates that are libraries the default is to have file called src/lib.rs so we can try to create that and a function called hello_in_lib_rs in it. In order to make it accessible from outside of the lib.rs file we also need to use the pub prefix in-front of the function declaration.

{% include file="examples/split-out-code-to-a-library/src/lib.rs" %}

Now comes the tricky part. How can we access this function?

The recommended way is to use the name of the crate.

In this example I used the name split-out-code-to-a-library. That became the name of the folder cargo created and it was also included in the Cargo.toml file:

{% include file="examples/split-out-code-to-a-library/Cargo.toml" %}

Those dashes between the words made sense when I created the crate, but we can't use them inside the code. So instead of that we use the same name, but we replace the dashes by underscores. So can call the function this way: split_out_code_to_a_library::hello_in_lib_rs(); from the main.rs file.

The problem I can see with this is that if we rename the crate by changing the package.name field in the Cargo.toml then we also have to change our code to reflect the new name.

I think, if in a crate that has a main.rs we would like to move some code to a separate file purely for better internal code organization, then it is probably better to use filenames other than lib.rs.

On the other hand if we would like to let other crates to use our functions then we should probably create a separate crate that has a lib.rs but has no main.rs.

other.rs

So what happens if we create another file called other.rs with a function called hello_in_other_rs in it? How can we call it from main.rs?

{% include file="examples/split-out-code-to-a-library/src/other.rs" %}

For this we needed 3 things. In the other.rs we had to use the pub prefix. (That stand for public and not "place to drink beer".)

We had to add mod other; to the main.rs and then we could use the name of the file to access the function in two different ways:

other::hello_in_other_rs(); says where relative to the main.rs file the other file and function can be found.

crate::other::hello_in_other_rs(); says where the other.rs file and the function is located starting from the root of the current crate.

In either case we only need to keep aligned with the internal name of the file and the internal directory hierarchy.

We can freely rename the crate to anything.