Tuesday, 23 March, 2021 UTC


In our subcommand match we'll add a new function called `write` to handle our `Write` subcommand. We'll pass it the argument title and we'll "import" it from a library called `digital_garden`. ```rust use digital_garden::write; fn main() -> Result { color_eyre::install()?; let opt = Opt::from_args(); dbg!(&opt); match opt.cmd { Command::Write { title } => write(title), } } ``` To create this library, add a new section in `Cargo.toml`. We can give our library a name and set which file to treat as the entrypoint. `src/lib.rs` is the default file for a library crate, but we can also be explicit about what we want to happen. ```toml [lib] name = "digital_garden" path = "src/lib.rs" ``` This leaves us with two crates, a binary crate, of which we can have any amount, and a library crate, of which we can only have 0 or 1. We'll create the `src/lib.rs` file with the following contents. ```rust mod write; pub use write::write; ``` Rust's module system is explicit, so when we write `mod write`, we are saying that the library `digital_garden` has a module `write`, such that the path to the module is `digital_garden::write`. In our case `digital_garden::write` corresponds to a file at `src/write.rs`. Secondly, the `pub use write::write` says that we have a function called `write` in the module called `write` and that the function will be exposed from lib publicly, so people who have the `digital_garden` library installed will be able to use the write function as `digital_garden::write`. In JavaScript the closest analogue is exporting a function from another file that exports it. ```js export { write } from './write.js'; ``` By using use, we're shortening the public path to the write function. A private module "write" with a function "write" also exists at `digital_garden::write::write`. If you try to use this path, Rust will tell you there is a private module there. Finally, in `src/write.rs`, we can write a public function that matches the return type of our main function, since we're using it as the return value from our match function. We'll accept an `Option` as an argument as well, since that's what we expect from the cli arguments. ```rust use color_eyre::Result; pub fn write(_title: Option) -> Result { todo!() } ``` The purpose of creating this module path is because we know that we're going to set up more modules for each subcommand in the future, and we can control both the placement of our code on disk, as well as the path users will interact with to use our module.