xdgkit/
user_dirs.rs

1/*! # User directories
2This reads the `~/config/user-dirs.dirs` file
3
4You can get the location of the file with `filename()`
5
6Or you can build a struct
7```
8use xdgkit::user_dirs::UserDirs;
9let user_dirs = UserDirs::new();
10// music directory
11let music = user_dirs.music; // usually ~/Music
12// documents directory
13let documents = user_dirs.documents; // usually ~/Documents
14// etc....
15```
16
17*/
18use std::fs::File;
19use std::io::{BufRead, BufReader};
20//use std::path::Path;
21use std::env::VarError;
22use crate::basedir;
23
24/// get the `user-dirs.dirs` full path + filename
25pub fn filename() -> Result<String, VarError> {
26    let conf_dir = match basedir::config_home() {
27        Ok(c) => c,
28        Err(e) => return Err(e),
29    };
30    Ok(format!("{}/user-dirs.dirs", conf_dir.as_str()))
31}
32
33/// The file is written by xdg-user-dirs-update
34/// it contains the locations of each directory
35#[derive(Clone, Debug)]
36pub struct UserDirs {
37    /// xdg default is: $HOME/Desktop
38    pub desktop:String,
39    /// xdg default is: $HOME/Downloads
40    pub download:String,
41    /// xdg default is: $HOME/Templates
42    pub template:String,
43    /// xdg default is: $HOME/Public
44    pub public_share:String,
45    /// xdg default is: $HOME/Documents
46    pub documents:String,
47    /// xdg default is: $HOME/Music
48    pub music:String,
49    /// xdg default is: $HOME/Pictures
50    pub pictures:String,
51    /// xdg default is: $HOME/Videos
52    pub videos:String,
53}
54impl UserDirs {
55    /// make and empty one
56    #[allow(dead_code)]
57    pub fn empty() -> Self {
58        Self {
59            desktop:String::new(),
60            download:String::new(),
61            template:String::new(),
62            public_share:String::new(),
63            documents:String::new(),
64            music:String::new(),
65            pictures:String::new(),
66            videos:String::new(),
67        }
68    }
69    /// Attempt to create and populate, or send an empty one
70    #[allow(dead_code)]
71    pub fn new() -> Self {
72        let mut desktop = String::new();
73        let mut download = String::new();
74        let mut template = String::new();
75        let mut public_share = String::new();
76        let mut documents = String::new();
77        let mut music = String::new();
78        let mut pictures = String::new();
79        let mut videos = String::new();
80        let file_name = match filename() {
81            Ok(f) => f,
82            Err(_) => return Self::empty(),
83        };
84        // try to get home directory
85        let home = match basedir::home() {
86            Ok(h) => h,
87            Err(_) => "$HOME".to_string(),
88        };
89        // try to open the file
90        let file = match File::open(file_name.as_str()) {
91            Ok(f) => f,
92            Err(_) => return Self::empty(),
93        };
94        let file_reader = BufReader::new(file);
95        for (_line_number, line) in file_reader.lines().enumerate() {
96            if line.is_err() {
97                continue;
98            }
99            let mut line = line.unwrap();
100            // check to see if the line is a comment
101            if let Some(position) = line.find('#') {
102                if position == 0 {
103                    continue;
104                }
105            }
106            line.retain(|c| c != '"');//remove_matches('"');
107            if let Some((var, dir)) = line.rsplit_once('=') {
108                let _stizzle = dir.replace("$HOME", home.as_str());
109                if var == "XDG_DESKTOP_DIR" {
110                    desktop = dir.to_string();
111                } else if var == "XDG_DOWNLOAD_DIR" {
112                    download = dir.to_string();
113                } else if var == "XDG_TEMPLATES_DIR" {
114                    template = dir.to_string();
115                } else if var == "XDG_PUBLICSHARE_DIR" {
116                    public_share = dir.to_string();
117                } else if var == "XDG_DOCUMENTS_DIR" {
118                    documents = dir.to_string();
119                } else if var == "XDG_MUSIC_DIR" {
120                    music = dir.to_string();
121                } else if var == "XDG_PICTURES_DIR" {
122                    pictures = dir.to_string();
123                } else if var == "XDG_VIDEOS_DIR" {
124                    videos = dir.to_string();
125                }
126            }
127        }
128        Self {
129            desktop,
130            download,
131            template,
132            public_share,
133            documents,
134            music,
135            pictures,
136            videos,
137        }
138    }
139}