1use error::BoolError;
6use glib_sys;
7use gstring::GString;
8use std;
9use std::ffi::{OsStr, OsString};
10use std::path::{Path, PathBuf};
11use std::ptr;
12use translate::*;
13use Error;
14
15pub fn get_program_name() -> Option<String> {
19 get_prgname()
20}
21
22pub fn get_prgname() -> Option<String> {
23 unsafe { from_glib_none(glib_sys::g_get_prgname()) }
24}
25
26pub fn set_program_name(name: Option<&str>) {
30 set_prgname(name)
31}
32
33pub fn set_prgname(name: Option<&str>) {
34 unsafe { glib_sys::g_set_prgname(name.to_glib_none().0) }
35}
36
37pub fn getenv<K: AsRef<OsStr>>(variable_name: K) -> Option<OsString> {
38 #[cfg(not(windows))]
39 use glib_sys::g_getenv;
40 #[cfg(windows)]
41 use glib_sys::g_getenv_utf8 as g_getenv;
42
43 unsafe { from_glib_none(g_getenv(variable_name.as_ref().to_glib_none().0)) }
44}
45
46pub fn setenv<K: AsRef<OsStr>, V: AsRef<OsStr>>(
47 variable_name: K,
48 value: V,
49 overwrite: bool,
50) -> Result<(), BoolError> {
51 #[cfg(not(windows))]
52 use glib_sys::g_setenv;
53 #[cfg(windows)]
54 use glib_sys::g_setenv_utf8 as g_setenv;
55
56 unsafe {
57 glib_result_from_gboolean!(
58 g_setenv(
59 variable_name.as_ref().to_glib_none().0,
60 value.as_ref().to_glib_none().0,
61 overwrite.to_glib(),
62 ),
63 "Failed to set environment variable"
64 )
65 }
66}
67
68pub fn unsetenv<K: AsRef<OsStr>>(variable_name: K) {
69 #[cfg(not(windows))]
70 use glib_sys::g_unsetenv;
71 #[cfg(windows)]
72 use glib_sys::g_unsetenv_utf8 as g_unsetenv;
73
74 unsafe { g_unsetenv(variable_name.as_ref().to_glib_none().0) }
75}
76
77pub fn environ_getenv<K: AsRef<OsStr>>(envp: &[OsString], variable: K) -> Option<OsString> {
78 unsafe {
79 from_glib_none(glib_sys::g_environ_getenv(
80 envp.to_glib_none().0,
81 variable.as_ref().to_glib_none().0,
82 ))
83 }
84}
85
86pub fn get_user_name() -> Option<OsString> {
87 #[cfg(not(all(windows, target_arch = "x86")))]
88 use glib_sys::g_get_user_name;
89 #[cfg(all(windows, target_arch = "x86"))]
90 use glib_sys::g_get_user_name_utf8 as g_get_user_name;
91
92 unsafe { from_glib_none(g_get_user_name()) }
93}
94
95pub fn get_real_name() -> Option<OsString> {
96 #[cfg(not(all(windows, target_arch = "x86")))]
97 use glib_sys::g_get_real_name;
98 #[cfg(all(windows, target_arch = "x86"))]
99 use glib_sys::g_get_real_name_utf8 as g_get_real_name;
100
101 unsafe { from_glib_none(g_get_real_name()) }
102}
103
104pub fn get_current_dir() -> Option<PathBuf> {
105 #[cfg(not(windows))]
106 use glib_sys::g_get_current_dir;
107 #[cfg(windows)]
108 use glib_sys::g_get_current_dir_utf8 as g_get_current_dir;
109
110 unsafe { from_glib_full(g_get_current_dir()) }
111}
112
113pub fn filename_to_uri<P: AsRef<Path>>(
114 filename: P,
115 hostname: Option<&str>,
116) -> Result<GString, Error> {
117 #[cfg(not(windows))]
118 use glib_sys::g_filename_to_uri;
119 #[cfg(windows)]
120 use glib_sys::g_filename_to_uri_utf8 as g_filename_to_uri;
121
122 let hostname = hostname.to_glib_none();
123 unsafe {
124 let mut error = std::ptr::null_mut();
125 let ret = g_filename_to_uri(filename.as_ref().to_glib_none().0, hostname.0, &mut error);
126 if error.is_null() {
127 Ok(from_glib_full(ret))
128 } else {
129 Err(from_glib_full(error))
130 }
131 }
132}
133
134pub fn filename_from_uri(uri: &str) -> Result<(std::path::PathBuf, Option<GString>), Error> {
135 #[cfg(not(windows))]
136 use glib_sys::g_filename_from_uri;
137 #[cfg(windows)]
138 use glib_sys::g_filename_from_uri_utf8 as g_filename_from_uri;
139
140 unsafe {
141 let mut hostname = ptr::null_mut();
142 let mut error = ptr::null_mut();
143 let ret = g_filename_from_uri(uri.to_glib_none().0, &mut hostname, &mut error);
144 if error.is_null() {
145 Ok((from_glib_full(ret), from_glib_full(hostname)))
146 } else {
147 Err(from_glib_full(error))
148 }
149 }
150}
151
152pub fn find_program_in_path<P: AsRef<Path>>(program: P) -> Option<PathBuf> {
153 #[cfg(not(all(windows, target_arch = "x86")))]
154 use glib_sys::g_find_program_in_path;
155 #[cfg(all(windows, target_arch = "x86"))]
156 use glib_sys::g_find_program_in_path_utf8 as g_find_program_in_path;
157
158 unsafe { from_glib_full(g_find_program_in_path(program.as_ref().to_glib_none().0)) }
159}
160
161pub fn get_home_dir() -> Option<std::path::PathBuf> {
162 #[cfg(not(all(windows, target_arch = "x86")))]
163 use glib_sys::g_get_home_dir;
164 #[cfg(all(windows, target_arch = "x86"))]
165 use glib_sys::g_get_home_dir_utf8 as g_get_home_dir;
166
167 unsafe { from_glib_none(g_get_home_dir()) }
168}
169
170pub fn get_tmp_dir() -> Option<std::path::PathBuf> {
171 #[cfg(not(all(windows, target_arch = "x86")))]
172 use glib_sys::g_get_tmp_dir;
173 #[cfg(all(windows, target_arch = "x86"))]
174 use glib_sys::g_get_tmp_dir_utf8 as g_get_tmp_dir;
175
176 unsafe { from_glib_none(g_get_tmp_dir()) }
177}
178
179pub fn mkstemp<P: AsRef<std::path::Path>>(tmpl: P) -> i32 {
180 #[cfg(not(windows))]
181 use glib_sys::g_mkstemp;
182 #[cfg(windows)]
183 use glib_sys::g_mkstemp_utf8 as g_mkstemp;
184
185 unsafe { g_mkstemp(tmpl.as_ref().to_glib_none().0) }
186}
187
188#[cfg(test)]
189mod tests {
190 use std::env;
191 use std::sync::Mutex;
192
193 lazy_static! {
195 static ref LOCK: Mutex<()> = Mutex::new(());
196 }
197
198 const VAR_NAME: &str = "function_environment_test";
199
200 fn check_getenv(val: &str) {
201 let _data = LOCK.lock().unwrap();
202
203 env::set_var(VAR_NAME, val);
204 assert_eq!(env::var_os(VAR_NAME), Some(val.into()));
205 assert_eq!(::getenv(VAR_NAME), Some(val.into()));
206
207 let environ = ::get_environ();
208 assert_eq!(::environ_getenv(&environ, VAR_NAME), Some(val.into()));
209 }
210
211 fn check_setenv(val: &str) {
212 let _data = LOCK.lock().unwrap();
213
214 ::setenv(VAR_NAME, val, true).unwrap();
215 assert_eq!(env::var_os(VAR_NAME), Some(val.into()));
216 }
217
218 #[test]
219 fn getenv() {
220 check_getenv("Test");
221 check_getenv("Тест"); }
223
224 #[test]
225 fn setenv() {
226 check_setenv("Test");
227 check_setenv("Тест"); }
229
230 #[test]
231 fn test_filename_from_uri() {
232 use gstring::GString;
233 use std::path::PathBuf;
234 let uri: GString = "file:///foo/bar.txt".into();
235 if let Ok((filename, hostname)) = ::filename_from_uri(&uri) {
236 assert_eq!(filename, PathBuf::from(r"/foo/bar.txt"));
237 assert_eq!(hostname, None);
238 } else {
239 unreachable!();
240 }
241
242 let uri: GString = "file://host/foo/bar.txt".into();
243 if let Ok((filename, hostname)) = ::filename_from_uri(&uri) {
244 assert_eq!(filename, PathBuf::from(r"/foo/bar.txt"));
245 assert_eq!(hostname, Some(GString::from("host")));
246 } else {
247 unreachable!();
248 }
249 }
250}