We want to build out functionality to let the user write into a file in their garden. To do that, we have to know the location of their garden.
We'll start by implementing a function to get the default garden path.
fn get_default_garden_dir() -> Result<PathBuf> {
let user_dirs = UserDirs::new().ok_or_else(|| eyre!("Could not find home directory"))?;
Ok(user_dirs.home_dir().join(".garden"))
}
This uses the user's system directories via the directories
crate to find their home dir. We then add .garden
to the home dir for the default garden.
Ideally, we would want the user to be able to specify their garden path. Using structopt, we can let them specify it as a short, long, or env var.
In our README, we'll specify how this should work.
```shell
GARDEN_PATH=~/github/my-digital-garden garden write
garden -p ~/github/my-digital-garden write
garden --garden_path ~/github/my-digital-garden write
```
And in our Opt
struct, we can tell structopt how to handle it. Putting this in our Opt
struct instead of our Command
enum make it a global flag that can be specified for all subcommands.
struct Opt {
#[structopt(parse(from_os_str), short = "p", long, env)]
garden_path: Option<PathBuf>,
#[structopt(subcommand)]
cmd: Command,
}
structopt is only handling the user input, so in main()
we still need to fall back to the default if the garden_path
is not specified.
let garden_path = match opt.garden_path {
Some(pathbuf) => Ok(pathbuf),
None => get_default_garden_dir().wrap_err("`garden_path` was not supplied"),
}?;
If we force an Err
in get_default_garden_dir
We can see how the wrapped errors end up stacking.
Error:
0: `garden_path` was not supplied
1: Could not find home directory
We'll also change the signature of write
to accept the pathbuf.
Command::Write { title } => write(garden_path, title),
Note that we need to import PathBuf
. We can also dbg!
the garden path and title to see their values.
use std::path::PathBuf;
pub fn write(garden_path: PathBuf, title: Option<String>) -> Result<()> {
dbg!(garden_path, title);
todo!()
}