In this workshop we're going to set up a MySQL database that will be used as a data source for two other serverless function workshops: One on Netlify and one on AWS.
Keeping that in mind we're going to make this project a Cargo workspace from the start so that those future crates can be developed alongside our csv code.
A Cargo Workspace allows us to work on multiple packages in a coordinated way.
This is a common method of organizing code in the Rust ecosystem and it enables some interesting use cases. For example, Nushell (a shell built in Rust) is organized as a workspace.
Nushell publishes the individual crates in its workspace. This allows other people to use crates that the Nushell project develops directly off of github without having to install the entire codebase, such as the crate responsible for pretty-printing fancy Tables.
Setting up a Cargo Workspace
All of the packages in a Cargo workspace will share the same
Cargo.lock at the root of the workspace and the same
target/ directory for build output.
To let cargo know where our crates will be located, we'll create a
Cargo.toml in the root of the project. The
Cargo.toml will specify that this is a
[workspace] and where the members of the workspace are. In this case we'll be keeping our crates in a directory called
crates, so we can tell cargo that any package in
crates is a member of the workspace using
We'll also specify that we want to use
resolver = "2". The default resolver version is
1, but the Rust 2021 edition defaults to
2, so we'll use that instead.
[workspace] members = ["crates/*"] resolver = "2"
Then we'll create the
crates directory, and our first package:
upload-pokemon-data. This is the package that will hold the binary that will parse and upload pokemon data from a CSV into our PlanetScale database.
mkdir crates cargo new crates/upload-pokemon-data
By default a new cargo package holds a binary crate with an entry point at
src/main.rs. This binary will be named the same as the package name, which in this case is
We can build and run the new binary using that name
cargo run --bin upload-pokemon-data
and the binary that gets built will be placed into the
target/debug/ directory from the root of our project. The
Cargo.lock file is also created in the root of our workspace, not the root of our package.
Since we only have a single binary, cargo can tell what you mean if you leave off
--bin and just run
cargo run. This will change when you have more binaries in the project in the future though so knowing how to specify which binary you want to run is important.
Depending on if you chose to create a git repository already or not,
cargo new could also have created a
.gitignore file in our new package, which we can move to the root of our project.
Otherwise, you can create a
/target specified in it at the root of our project.