profile.rs (3737B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 use crate::preferences::{Pref, Preferences}; 6 use crate::prefreader::{parse, serialize, PrefReaderError}; 7 use std::collections::btree_map::Iter; 8 use std::fs::File; 9 use std::io::prelude::*; 10 use std::io::Result as IoResult; 11 use std::path::{Path, PathBuf}; 12 use tempfile::{Builder, TempDir}; 13 14 #[derive(Debug)] 15 pub struct Profile { 16 pub path: PathBuf, 17 pub temp_dir: Option<TempDir>, 18 prefs: Option<PrefFile>, 19 user_prefs: Option<PrefFile>, 20 } 21 22 impl PartialEq for Profile { 23 fn eq(&self, other: &Profile) -> bool { 24 self.path == other.path 25 } 26 } 27 28 impl Profile { 29 pub fn new(temp_root: Option<&Path>) -> IoResult<Profile> { 30 let mut dir_builder = Builder::new(); 31 dir_builder.prefix("rust_mozprofile"); 32 let dir = if let Some(temp_root) = temp_root { 33 dir_builder.tempdir_in(temp_root) 34 } else { 35 dir_builder.tempdir() 36 }?; 37 let path = dir.path().to_path_buf(); 38 let temp_dir = Some(dir); 39 Ok(Profile { 40 path, 41 temp_dir, 42 prefs: None, 43 user_prefs: None, 44 }) 45 } 46 47 pub fn new_from_path(p: &Path) -> IoResult<Profile> { 48 let path = p.to_path_buf(); 49 let temp_dir = None; 50 Ok(Profile { 51 path, 52 temp_dir, 53 prefs: None, 54 user_prefs: None, 55 }) 56 } 57 58 pub fn prefs(&mut self) -> Result<&mut PrefFile, PrefReaderError> { 59 if self.prefs.is_none() { 60 let mut pref_path = PathBuf::from(&self.path); 61 pref_path.push("prefs.js"); 62 self.prefs = Some(PrefFile::new(pref_path)?) 63 }; 64 // This error handling doesn't make much sense 65 Ok(self.prefs.as_mut().unwrap()) 66 } 67 68 pub fn user_prefs(&mut self) -> Result<&mut PrefFile, PrefReaderError> { 69 if self.user_prefs.is_none() { 70 let mut pref_path = PathBuf::from(&self.path); 71 pref_path.push("user.js"); 72 self.user_prefs = Some(PrefFile::new(pref_path)?) 73 }; 74 // This error handling doesn't make much sense 75 Ok(self.user_prefs.as_mut().unwrap()) 76 } 77 } 78 79 #[derive(Debug)] 80 pub struct PrefFile { 81 pub path: PathBuf, 82 pub prefs: Preferences, 83 } 84 85 impl PrefFile { 86 pub fn new(path: PathBuf) -> Result<PrefFile, PrefReaderError> { 87 let prefs = if !path.exists() { 88 Preferences::new() 89 } else { 90 let mut f = File::open(&path)?; 91 let mut buf = String::with_capacity(4096); 92 f.read_to_string(&mut buf)?; 93 parse(buf.as_bytes())? 94 }; 95 96 Ok(PrefFile { path, prefs }) 97 } 98 99 pub fn write(&self) -> IoResult<()> { 100 let mut f = File::create(&self.path)?; 101 serialize(&self.prefs, &mut f) 102 } 103 104 pub fn insert_slice<K>(&mut self, preferences: &[(K, Pref)]) 105 where 106 K: Into<String> + Clone, 107 { 108 for (name, value) in preferences.iter() { 109 self.insert((*name).clone(), (*value).clone()); 110 } 111 } 112 113 pub fn insert<K>(&mut self, key: K, value: Pref) 114 where 115 K: Into<String>, 116 { 117 self.prefs.insert(key.into(), value); 118 } 119 120 pub fn remove(&mut self, key: &str) -> Option<Pref> { 121 self.prefs.remove(key) 122 } 123 124 pub fn get(&mut self, key: &str) -> Option<&Pref> { 125 self.prefs.get(key) 126 } 127 128 pub fn contains_key(&self, key: &str) -> bool { 129 self.prefs.contains_key(key) 130 } 131 132 pub fn iter(&self) -> Iter<'_, String, Pref> { 133 self.prefs.iter() 134 } 135 }