@@ -16,25 +16,27 @@ use tectonic_errors::prelude::*;
1616/// The instance of the `directories` crate that this crate links to.
1717pub use directories;
1818
19- const PROJECT_DIRS : LazyLock < ProjectDirs > =
20- LazyLock :: new ( || ProjectDirs :: from ( "" , "TectonicProject" , "Tectonic" ) . unwrap ( ) ) ;
19+ const PROJECT_DIRS : LazyLock < Result < ProjectDirs > > = LazyLock :: new ( || {
20+ ProjectDirs :: from ( "" , "TectonicProject" , "Tectonic" )
21+ . ok_or_else ( || Error :: from ( "Unable to find standard directories for platform" ) )
22+ } ) ;
2123
2224/// Get the directory for per-user Tectonic configuration files.
2325///
2426/// This constructs the path but does not ensure that the directory actually
2527/// exists. The function [`ensure_user_config`] makes sure that the directory is
2628/// created.
2729///
28- /// This function is currently implemented with [`app_dirs2::get_app_root `] using
29- /// the `UserConfig ` data type. Return values have the form:
30+ /// This function is currently implemented with [`ProjectDirs::config_dir `] using
31+ /// the `ProjectDirs ` data type. Return values have the form:
3032///
3133/// - Windows: `%APPDATA%\TectonicProject\Tectonic`, where `%APPDATA%` is
3234/// something like `C:\Users\knuth\AppData\Roaming`.
3335/// - macOS: `$HOME/Library/Application Support/Tectonic`
3436/// - Others: `$XDG_CONFIG_HOME/Tectonic` if defined, otherwise
3537/// `$HOME/.config/Tectonic`
3638pub fn get_user_config ( ) -> Result < PathBuf > {
37- Ok ( PROJECT_DIRS . config_dir ( ) . to_path_buf ( ) )
39+ Ok ( PROJECT_DIRS ? . config_dir ( ) . to_path_buf ( ) )
3840}
3941
4042/// Get the directory for per-user Tectonic configuration files, creating it if needed.
@@ -53,8 +55,8 @@ pub fn ensure_user_config() -> Result<PathBuf> {
5355/// should be a forward slash on all platforms. It may be an empty string if you
5456/// want to get the toplevel user cache directory.
5557///
56- /// This function is currently implemented with [`app_dirs2::app_dir `] using the
57- /// `UserCache ` data type. Return values have the form:
58+ /// This function is currently implemented with [`ProjectDirs::cache_dir `] using the
59+ /// `ProjectDirs ` data type. Return values have the form:
5860///
5961/// - Windows: `%LOCALAPPDATA%\TectonicProject\Tectonic`, where `%LOCALAPPDATA%`
6062/// is something like `C:\Users\knuth\AppData\Local`.
@@ -63,12 +65,12 @@ pub fn ensure_user_config() -> Result<PathBuf> {
6365/// `$HOME/.cache/Tectonic`
6466///
6567///
66- /// The cache location defaults to the `AppDataType::UserCache `
67- /// provided by `app_dirs2 ` but can be overwritten using the
68+ /// The cache location defaults to the `ProjectDirs::cache_dir `
69+ /// provided by `directories ` but can be overwritten using the
6870/// `TECTONIC_CACHE_DIR` environment variable.
6971///
7072/// This method may perform I/O to create the user cache directory, so it is
71- /// fallible. (Due to its `app_dirs2 ` implementation, it would have to be
73+ /// fallible. (Due to its `directories ` implementation, it would have to be
7274/// fallible even if it didn't perform I/O.)
7375pub fn get_user_cache_dir ( subdir : & str ) -> Result < PathBuf > {
7476 let env_cache_path = env:: var_os ( "TECTONIC_CACHE_DIR" ) ;
@@ -80,8 +82,28 @@ pub fn get_user_cache_dir(subdir: &str) -> Result<PathBuf> {
8082 fs:: create_dir_all ( & env_cache_path) ?;
8183 env_cache_path
8284 }
83- None => PROJECT_DIRS . cache_dir ( ) . join ( subdir) ,
85+ None => PROJECT_DIRS ? . cache_dir ( ) . join ( subdir) ,
8486 } ;
8587
8688 Ok ( cache_path)
8789}
90+
91+ /// Borrowed from `app_dirs2`, convert any string into a consistently valid file or directory name.
92+ pub fn sanitize ( component : & str ) -> String {
93+ let mut buf = String :: with_capacity ( component. len ( ) ) ;
94+ for ( i, c) in component. chars ( ) . enumerate ( ) {
95+ let is_alnum = c. is_ascii_alphanumeric ( ) ;
96+ let is_space = c == ' ' ;
97+ let is_hyphen = c == '-' ;
98+ let is_underscore = c == '_' ;
99+ let is_period = c == '.' && i != 0 ; // Disallow accidentally hidden folders
100+ let is_valid = is_alnum || is_space || is_hyphen || is_underscore || is_period;
101+ if is_valid {
102+ buf. push ( c) ;
103+ } else {
104+ use std:: fmt:: Write ;
105+ let _ = write ! ( & mut buf, ",{}," , c as u32 ) ;
106+ }
107+ }
108+ buf
109+ }
0 commit comments