Optimizing My Rust Development Environment
We were commanded by the powers that be for our team to be the "guinea pig" that migrates to Rust. My approach entailed configuring various tools I liked as a Python developer for my Rust Development Environment (RDE). I was surprised when the other team members incorporated many of my RDE approaches. I am sharing the details with you.

It would be a very dull world if all used the same name for the same concept.
But when you think about it, the terms do not mean the same concepts for solid reasons: each term is different.

The dependencies in Rust and Python diverge due to the fundamental dissimilarities in their language paradigms and packaging formats.
Rust is a statically-typed compiled language that distributes packages, known as crates, in precompiled binaries. Conversely, Python is a dynamically-typed interpreted language that distributes its packages as source code.
The difference in distribution methods impacts the installation and management of dependencies in each language.
Rust's package manager, Cargo, is integrated with the compiler and enables hassle-free dependency management. Conversely, Python has several package managers, with Pip being the most popular.
Cargo's dependency resolution algorithm guarantees compatibility between all packages, facilitating the management of dependencies and minimizing version conflicts. Python's dependency resolution is more relaxed, sometimes resulting in version conflicts.
These discrepancies between dependencies in Rust and Python ultimately stem from each language's unique priorities and design goals.
Rust emphasizes the performance of a strongly typed compiled language, threading for modern multi-core computers, and safety for C. Python emphasizes ease of use and readability.
Installing Rust and Cargo
The installation that my teammates and I use is from https://doc.rust-lang.org/book/ch01-01-installation.html. The Rust community supports it, and it is quick, less than 1 minute, on my MacPro 2013 with the old Intell Xeon E5 chipset.
curl https://sh.rustup.rs -sSf | sh

Note:
sh
might not work. use/bin/bash
Jupyter is not an Integrated Development Environment (IDE)
Jupyter is an interactive computing and data exploration environment, quite popular with the Python and Machine Learning community. The emphasis for me is Interactive Computing Environment (ICS), also known as a Read-Eval-Print Loop or REPL editor.
I started my career in computing on an IBM 360 using punch cards and getting in one compile every 12 hours; if my day started at 2:00 AM.
I use Jupyter for Python.
Something else will best Jupyter, but using Python and Jupyter; I have evolved from compiles per hour to how many functions I can write per hour with five unit tests.
No lie. I am approximately 25 times more productive with Python/Jupyter than with C/Emacs.
Jupyter possesses certain features commonplace in Integrated Development Environments (IDEs), including code editing and debugging.
The fundamental objective of Jupyter is to enable interactive computing, data analysis, and exploratory programming, which renders it an indispensable tool for tasks such as coding and debugging, as well as data cleaning, transformation, and visualization.
I use both an ICS and an IDE. I use an ICS, Jupyter, to mature a bunch of related functions, and for an IDE, I use Pycharm with Rust plugin to roll out to Test. I describe in more detail the Rust plugin later in this article.
How to configure Jupyter as an ICS for Rust
I want Jupyter to experiment with Rust code.
ExCxR
for Jupyter is an open-source project (free!) that enables Rust code to be executed in a Jupyter notebook.
To use Rust in Jupyter, you must install and put the kernel in your Jupyter environment.
I show you step-by-step:
Note: I assume you are familiar with Python. If not, I recommend using the Rust documentation.
- You probably have Jupyter already installed. If you do not, install Jupyter via the Python loader pip:
pip install jupyter
2. Next, download and build the evcxr
crate by running the following command in your terminal:
cargo install evcxr_jupyter

3. Next, install the evcxr_jupyter
kernel by running the following command in your terminal:
evcxr_jupyter --install

4. You can start a Jupyter notebook server using the jupyter notebook
command:
jupyter notebook
5. Create a new Rust notebook: In the Jupyter notebook interface, click on "New" -> "Rust" to create a new Rust notebook.

6. Copy and paste the code from the previous answer into a cell in the notebook.
7. Run the code by pressing Shift+Enter
or clicking on the "Run" button in the notebook interface. Here's an example of how the Rust "Hello, world" code and output appear in a Jupyter notebook:

A Hello-World function compiled and executed in Jupyter! That is so cool!
Here's an example of a recursive version of the Fibonacci function in Rust to calculate the nth Fibonacci number:

Note: Break
evcxr_jupyter
withfibnacci(100).
Note: You may need to adjust the Jupyter notebook settings to display the output of the Rust program, which may not be displayed by default. You can do this by selecting “Cell” -> “All Output” -> “Toggle Scrolling” from the menu bar.
Comments
A great feature of Python is its readability by humans.
With Rust, if you wrote the code, it is readable that day. Next month, not so much.
If you release your Rust code to Test without comments or harmful comments, your code will be one of the last to pass Test. How unfair!
Note: We test but we call the quality control group — Test.
Rust has an official style guide for comments, found in the Rust documentation.
At least we think we understand what the Rust community accomplished with their comment style guide. It can also be used as a style guide for C.
However, IMHO, Rust needs a lot of commenting to be readable.
Here is what we did for our style guide. We merged the "Google Rust Style Guide" and the "Google Python Style Guide" and came up with two Rust comment style rules:
- Use doc comments to document crates, functions, methods, structs, enums, traits, and modules. A doc comment is a comment that starts with /// or /**. The documentation provides a high-level overview of what the item does, how it works, and any important details relevant to users of the item.
For example:
/// functiion sum: Returns the sum of two numbers.
/// # Examples
///
/// ```
/// let result = sum(2, 3);
/// assert_eq!(result, 5);
/// ```
fn sum(a: i32, b: i32) -> i32 {
a + b
}
Arguments are undocumented in this example as they self-document the name, argument name, and type. If the arguments used are non-obvious, then they should be documented.
2. Do not use inline comments. If you feel you must use /* ... */
ON THE LINE ABOVE to provide implementation details irrelevant to code users.
Use inline comments sparingly and only when necessary. Inline comments should provide additional context or explain tricky code, but the code should be self-explanatory whenever possible.
For example:
fn main() {
let x = 5; // BAD INLINE COMMENT Initialize x to 5
// GOOD, BUT NOT REALLY. SORT OF OBEYS STYLE RULE
// Add 2 to x to get y
let y = x + 2;
println!("The value of x is {} and the value of y is {}", x, y);
}
We are using comments in our Rust code, so it is well-documented and readable for you and others who may follow.
Remember, we are (were) heavily influenced by Python, and are beginners at Rust. Our Rust comment practices may not be suitable for you.
There will probably be further evolution in our Rust comment (doc) practices.
Rust Integrated Development Environments( IDEs)
All the information was gathered from developer blog sites, programmer gossip, and sometimes product documentation.
The features of the IDE we use now, JetBrains PyCharm ( or IntelliJ IDEA) with Rust Plugin, deserves one or more blog articles. No promises, but you may see them in the future.
There are more than eight IDEs that I know of. I’ve briefly discussed four IDEs (Integrated Development Environments) that support multi-languages, including Rust in this external blog.
Visual Studio for Rust
If you are on a Windows platform, I have heard from other colleagues that Visual Studio is a great IDE for Rust. It might be great for MacOS and Linux. However, we stopped our evaluation at the Visual Studio for Rust documentation. It was not present for the macOS. We may not have looked hard enough. There was excellent documentation for Microsoft Windows.
Imagine our surprise when we concluded that Microsoft needed to support Apple's macOS or Linux fully.
Note: OK, we were not that surprised.
JetBrains IntelliJ IDEA Rust plugin
We choose the JetBrains plugin for Rust. Installing the Rust plugin into PyCharm was effortless.
Also, it had a tremendous but useless feature. If we launched PyCharm before loading, the Rust plugin download page would change.

Install the Rust plugin, and then you may have to restart PyCharm.

The documentation for IntelL (PyCharm) plugin is quite good, IMHO.
The PyCharm plugin for Rust features:
- Code highlighting and completion;
- Cargo integration: The plugin integrates with Cargo, Rust's package manager (project manager) ;
- Seamless integration with GitHub;
- Debugging: The plugin includes a built-in debugger;
- Testing: The plugin includes support for running Rust tests and provides a test runner tool window to display test results.
- Documentation: The plugin provides quick access to Rust documentation within the IDE.
If there is enough interest, as shown in the comments, I will write a blog article on the various features we use in the IntelliJ IDEA plugin for Rust.
Eclipse
We used Eclipse for a small Scala project. It was ok. We found it took up a large memory footprint, took a long time to load, and was awkward to use. Admittedly, we used it two years ago and were already using PyCharm.
If you are unfamiliar with a Rust IDE, Eclipse is a good choice.
Emacs
If you have used Emacs for 30 years or more, you should stay with Emacs. If you invested heavily in Lisp (Scheme) macros, you want to stay with Emacs.
The great news is that Emacs is a highly customizable (Lisp) text editor with good Rust support in Rust mode. The bad news is you will be lonely.
Versioning, Dependencies, Compatibility
I am not sure if I should tell you, but you can compile and run using the command rustc.
Nobody, literally, nobody I know uses rustc,
everybody I know uses cargo.
If you installed the rust environment, following the install procedure I laid out above, then typing at your terminal should result in something like the following:

If it does not display a version, try the install again.
Most of the rest of this blog article is going to be confusing until you get cargo
working.
Cargo
Most Rustaceans use this tool (cargo) to manage their Rust projects because Cargo handles a lot of tasks for you… rust documentation.
Cargo benefits from all the package managers that came before it. Pip is a great example of a less-than-optimal package manager.
- Cargo is a part of Rust. Cargo is (usually) installed with Rust;
cargo new <project-name>
creates the directory<project-name>,
puts a minimal sub-directory structure, initializes it as a local git repository, and creates the importantcargo.toml
.
Alternatively, you can join an existing project that has an existing Rust git server repository. For example, the repo for this blog article is https://github.com/bcottman/rustDevEnv.
# cd <to directory to place local copy of repo>
$ git clone https://github.com/bcottman/rustDevEnv.git
$ cd rustDevEnv
$ ls -alx
The directory structure and files after a git clone
for the rustDevEnv
project are:

We found it best, as we usually have more than one developer working on a project, to have one developer :
- Create the rust project using
cargo new <project-name>
; - Then create a repo of the project on a git server.
All other developers can now clone off the git server repo.
Note: If you had a git version for over a year, you should upgrade. The git version I am using:

3. cargo build
completes initializing the local project as a rust project with src/main.rs(code for hello world),
compiles, downloads dependencies (crates) specified in cargo.toml
file, and links to produce the executable. The local project directory is now:

Great. cargo build
is pointing out that I should use rest_dev_env
, not restDevEnv.
4. cargo check
compiles but does not produce the executable. It is faster and therefore you can get more compiles per millisecond.

5. cargo build --release
to compile it with optimizations and places the executable in ../target/release.

6. cargo run

7. cargo test
searches for the#[test]
attribute in your Rust code to run them as tests.
8. rustdoc src/<filename> -crate-name <name>

Note: I consider cargo to be a Continuous Development (CD) Project Manager. CD is part of the CD/CI that defines DevOps.
Literate Programming
About two years ago, I discussed a twenty-year-old idea by Donald Knuth called "literate programming."
The key idea is that code, and associated tests and documentation for that code are located in one source file. Of course, you could have many different source files in your project (crate).
For me, cargo
achieves "literate programming" for Rust.
The other significant benefit of cargo
is that it manages dependencies and ensures compatibility between different versions of Rust crates. Also, cargo
is tightly integrated with Git and fetches dependencies from Git repositories.
Jupyter needs to work with a rust project.
Earlier, I discussed the wonders of Juptyer's compatibility with Rust. I implied that you could put any rust code in Jupyter and evaluate it.
You can do this so long as the Rust code does not have dependent crates. For example, the following Rust code cut&paste into a Jupyter notebook fails:
extern crate num_cpus;
fn main() {
let num_cores = num_cpus::get();
println!("Number of cores: {}", num_cores);
}
main()
However, it will work if you used to set up a Rust project withcargo build
and put num_cpus
in crate.toml
as a crate dependency.

It is worth repeating, Jupyter must be run in a project directory with all dependent crates specified in the file crate.toml.
Note: It may be obvious to you, but it was not to us, that you need to put each crate and the version number of that crate in the
[dependecy]
section ofcrate.toml.
Dependectcy listing in crate.toml is not generated from source code. It could be. Let me if there is a tool that does this.
Note: The crates available, about 50,000, and version numbers are found at https://crates.io/. FYI, pyhon has about 500,000 packages at https://pypi.org/.
Testing
cargo test
is a command-line tool that is included with Rust's Cargo build system. It is used to run the tests in a Rust project.
Add the #[test] attribute to mark your code as test code.
When you run cargo test
, Cargo will compile your project's code, including any unit tests, and run them.
To specialize your tests, you can use various command-line options to control which tests are run. For example:
cargo test <test_name>
will run only the test with the specified name.cargo test -- --ignored
will run only the tests that have been marked with the#[ignore]
attribute.cargo test --release
will run the tests with optimizations enabled, making them faster and debugging more difficult.
Additionally cargo test
after running the specified tests, it will output the results of the tests to the console. The output will include information about which tests passed and failed, as well as any output generated by the tests themselves.
I show how cargo test
behaves by starting with an example implementation of a recursive Fibonacci function with a degree n
as:
fn fibonacci(n: i32) -> i32 {
if n < 0 {
panic!("Fibonacci sequence is only defined for non-negative numbers");
}
if n == 0 {
0
} else if n == 1 {
1
} else {
fibonacci(n - 1) + fibonacci(n - 2)
}
}
Adding unit tests is straightforward:
#[test]
fn test_fbonacci_first() {
assert_eq!(fibonacci(0), 0);
}
#[test]
fn test_fbonacci_fail() {
assert_eq!(fibonacci(0), -1);
}
#[test]
fn test_fbonacci_rest() {
assert_eq!(fibonacci(1), 1);
assert_eq!(fibonacci(2), 1);
assert_eq!(fibonacci(3), 2);
assert_eq!(fibonacci(4), 3);
assert_eq!(fibonacci(5), 5);
assert_eq!(fibonacci(6), 8);
assert_eq!(fibonacci(7), 13);
}
cargo test
in the RustDevEnv
project, and the resulting output is:

If you want to get more complicated with your testing, and I hope you do, then please read https://doc.rust-lang.org/book/ch11-01-writing-tests.html.
I have given a taste of what you can do for testing in Rust. Other crates you should look at:
- Criterion.rs is an excellent crate for benchmarking your Rust code. It provides statistical analysis of benchmark results and allows you to compare the performance of different implementations.
- Proptest is a property-based testing framework that generates random inputs to ensure your code behaves correctly for all possible inputs. It's a powerful tool for catching edge cases and improving the reliability of your code.
- If your Rust code depends on external dependencies, Mockers is a great tool for writing tests. It allows you to define mock objects and verify that they're being used correctly.
There are many more Rust test frameworks, and more are being released daily. Please keep evaluating Rust test tools as they appear. I know I will.
Future Work
Where do I start? Rust is an entirely new language ecosystem for me.
Here are a couple of questions I have.
Polar is a big hit with our group. For those unfamiliar with Polars, it is a Rust implementation of Pandas that is fast and solves most of the big data problems that Pandas has. There must be other Python packages that are in Rust. What are they? What new crates can we expect?
Should we use Rust git tools or be locked in with Github actions?
I did not discuss debuggers in this blog article because we are still deciding on debuggers. The internal argument is, do we stick with the IntelliJ Rust plugin debugger? Will it get better?
I am sure there will be more questions. What I like about Rust so far is that it fixes many problems with C. I am uncomfortable with the lack of object-oriented in the core of Rust.
Rust++? No comment.
Remember you get the RustDevEnv and all associated code by cloning the GitHub repo at https://github.com/bcottman/rustDevEnv.
Resources
JetBrian's (IntelliJ IDEA) Rust Plugin
Mac IDE — Develop Apps & Games on Mac OS
Example Google Style Python Docstrings
Documentation for Visual Studio Code
crates.io: Rust Package Registry
Thanks!