The Pokemon CSV upload project is going to be the basis for other courses that need data in a Planetscale database, such as deploying a serverless pokemon API on netlify, so keeping that in mind we're going to make this project a Cargo workspace from the start.
A Cargo workspace allows us to work on multiple packages while also keeping them in separate crates that we could publish independently if we wanted to. This is a common method of organizing code in the Rust ecosystem and it allows interesting use cases. For example, Nushell, a Rust shell, is organized as a 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.
All of the packages in a Cargo workspace will share the same Cargo.lock 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 crates/*
.
[workspace]
members = ["crates/*"]
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 upload-pokemon-data
.
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. The Cargo.lock
file is also created in the root of our workspace, not the root of our package.
cargo new
also created a .gitignore
file in our new package, which we can move to the root of our project