1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
use crate::not_found; use cap_std::{ambient_authority, fs::Dir, AmbientAuthority}; use std::{fs, io}; /// `ProjectDirs` computes the cache, config or data directories for a specific /// application, which are derived from the standard directories and the name /// of the project/organization. /// /// This corresponds to [`directories_next::ProjectDirs`], except that the /// functions create the directories if they don't exist, open them, and return /// `Dir`s instead of returning `Path`s. /// /// Unlike `directories_next::ProjectDirs`, this API has no /// `ProjectDirs::from_path`, `ProjectDirs::path` or /// `ProjectDirs::project_path`, and the `*_dir` functions return `Dir`s rather /// than `Path`s, because absolute paths don't interoperate well with the /// capability model. #[derive(Clone)] pub struct ProjectDirs { inner: directories_next::ProjectDirs, } impl ProjectDirs { /// Creates a `ProjectDirs` struct from values describing the project. /// /// This corresponds to [`directories_next::ProjectDirs::from`]. /// /// # Ambient Authority /// /// This function makes use of ambient authority to access the project /// directories. pub fn from( qualifier: &str, organization: &str, application: &str, _: AmbientAuthority, ) -> Option<Self> { let inner = directories_next::ProjectDirs::from(qualifier, organization, application)?; Some(Self { inner }) } /// Returns the project's cache directory. /// /// This corresponds to [`directories_next::ProjectDirs::cache_dir`]. pub fn cache_dir(&self) -> io::Result<Dir> { let path = self.inner.cache_dir(); fs::create_dir_all(path)?; Dir::open_ambient_dir(path, ambient_authority()) } /// Returns the project's config directory. /// /// This corresponds to [`directories_next::ProjectDirs::config_dir`]. pub fn config_dir(&self) -> io::Result<Dir> { let path = self.inner.config_dir(); fs::create_dir_all(path)?; Dir::open_ambient_dir(path, ambient_authority()) } /// Returns the project's data directory. /// /// This corresponds to [`directories_next::ProjectDirs::data_dir`]. pub fn data_dir(&self) -> io::Result<Dir> { let path = self.inner.data_dir(); fs::create_dir_all(path)?; Dir::open_ambient_dir(path, ambient_authority()) } /// Returns the project's local data directory. /// /// This corresponds to [`directories_next::ProjectDirs::data_local_dir`]. pub fn data_local_dir(&self) -> io::Result<Dir> { let path = self.inner.data_local_dir(); fs::create_dir_all(path)?; Dir::open_ambient_dir(path, ambient_authority()) } /// Returns the project's runtime directory. /// /// This corresponds to [`directories_next::ProjectDirs::runtime_dir`]. pub fn runtime_dir(&self) -> io::Result<Dir> { let path = self.inner.runtime_dir().ok_or_else(not_found)?; fs::create_dir_all(path)?; Dir::open_ambient_dir(path, ambient_authority()) } }