1 // Take a look at the license at the top of the repository in the LICENSE file.
2
3 use crate::error::BoolError;
4 use crate::gstring::GString;
5 use crate::translate::*;
6 use crate::Error;
7 use std::ffi::{OsStr, OsString};
8 use std::path::{Path, PathBuf};
9 use std::ptr;
10
11 /// Same as [`get_prgname()`].
12 ///
13 /// [`get_prgname()`]: fn.get_prgname.html
14 #[doc(alias = "get_program_name")]
program_name() -> Option<String>15 pub fn program_name() -> Option<String> {
16 prgname()
17 }
18
19 #[doc(alias = "g_get_prgname")]
20 #[doc(alias = "get_prgname")]
prgname() -> Option<String>21 pub fn prgname() -> Option<String> {
22 unsafe { from_glib_none(ffi::g_get_prgname()) }
23 }
24
25 /// Same as [`set_prgname()`].
26 ///
27 /// [`set_prgname()`]: fn.set_prgname.html
set_program_name(name: Option<&str>)28 pub fn set_program_name(name: Option<&str>) {
29 set_prgname(name)
30 }
31
32 #[doc(alias = "g_set_prgname")]
set_prgname(name: Option<&str>)33 pub fn set_prgname(name: Option<&str>) {
34 unsafe { ffi::g_set_prgname(name.to_glib_none().0) }
35 }
36
37 #[doc(alias = "g_getenv")]
getenv<K: AsRef<OsStr>>(variable_name: K) -> Option<OsString>38 pub fn getenv<K: AsRef<OsStr>>(variable_name: K) -> Option<OsString> {
39 #[cfg(not(windows))]
40 use ffi::g_getenv;
41 #[cfg(windows)]
42 use ffi::g_getenv_utf8 as g_getenv;
43
44 unsafe { from_glib_none(g_getenv(variable_name.as_ref().to_glib_none().0)) }
45 }
46
47 #[doc(alias = "g_setenv")]
setenv<K: AsRef<OsStr>, V: AsRef<OsStr>>( variable_name: K, value: V, overwrite: bool, ) -> Result<(), BoolError>48 pub fn setenv<K: AsRef<OsStr>, V: AsRef<OsStr>>(
49 variable_name: K,
50 value: V,
51 overwrite: bool,
52 ) -> Result<(), BoolError> {
53 #[cfg(not(windows))]
54 use ffi::g_setenv;
55 #[cfg(windows)]
56 use ffi::g_setenv_utf8 as g_setenv;
57
58 unsafe {
59 result_from_gboolean!(
60 g_setenv(
61 variable_name.as_ref().to_glib_none().0,
62 value.as_ref().to_glib_none().0,
63 overwrite.into_glib(),
64 ),
65 "Failed to set environment variable"
66 )
67 }
68 }
69
70 #[doc(alias = "g_unsetenv")]
unsetenv<K: AsRef<OsStr>>(variable_name: K)71 pub fn unsetenv<K: AsRef<OsStr>>(variable_name: K) {
72 #[cfg(not(windows))]
73 use ffi::g_unsetenv;
74 #[cfg(windows)]
75 use ffi::g_unsetenv_utf8 as g_unsetenv;
76
77 unsafe { g_unsetenv(variable_name.as_ref().to_glib_none().0) }
78 }
79
80 #[doc(alias = "g_environ_getenv")]
environ_getenv<K: AsRef<OsStr>>(envp: &[OsString], variable: K) -> Option<OsString>81 pub fn environ_getenv<K: AsRef<OsStr>>(envp: &[OsString], variable: K) -> Option<OsString> {
82 unsafe {
83 from_glib_none(ffi::g_environ_getenv(
84 envp.to_glib_none().0,
85 variable.as_ref().to_glib_none().0,
86 ))
87 }
88 }
89
90 #[doc(alias = "g_get_user_name")]
91 #[doc(alias = "get_user_name")]
user_name() -> OsString92 pub fn user_name() -> OsString {
93 #[cfg(not(all(windows, target_arch = "x86")))]
94 use ffi::g_get_user_name;
95 #[cfg(all(windows, target_arch = "x86"))]
96 use ffi::g_get_user_name_utf8 as g_get_user_name;
97
98 unsafe { from_glib_none(g_get_user_name()) }
99 }
100
101 #[doc(alias = "g_get_real_name")]
102 #[doc(alias = "get_real_name")]
real_name() -> OsString103 pub fn real_name() -> OsString {
104 #[cfg(not(all(windows, target_arch = "x86")))]
105 use ffi::g_get_real_name;
106 #[cfg(all(windows, target_arch = "x86"))]
107 use ffi::g_get_real_name_utf8 as g_get_real_name;
108
109 unsafe { from_glib_none(g_get_real_name()) }
110 }
111
112 #[doc(alias = "g_get_current_dir")]
113 #[doc(alias = "get_current_dir")]
current_dir() -> Option<PathBuf>114 pub fn current_dir() -> Option<PathBuf> {
115 #[cfg(not(windows))]
116 use ffi::g_get_current_dir;
117 #[cfg(windows)]
118 use ffi::g_get_current_dir_utf8 as g_get_current_dir;
119
120 unsafe { from_glib_full(g_get_current_dir()) }
121 }
122
123 #[doc(alias = "g_filename_to_uri")]
filename_to_uri<P: AsRef<Path>>( filename: P, hostname: Option<&str>, ) -> Result<GString, Error>124 pub fn filename_to_uri<P: AsRef<Path>>(
125 filename: P,
126 hostname: Option<&str>,
127 ) -> Result<GString, Error> {
128 #[cfg(not(windows))]
129 use ffi::g_filename_to_uri;
130 #[cfg(windows)]
131 use ffi::g_filename_to_uri_utf8 as g_filename_to_uri;
132
133 let hostname = hostname.to_glib_none();
134 unsafe {
135 let mut error = std::ptr::null_mut();
136 let ret = g_filename_to_uri(filename.as_ref().to_glib_none().0, hostname.0, &mut error);
137 if error.is_null() {
138 Ok(from_glib_full(ret))
139 } else {
140 Err(from_glib_full(error))
141 }
142 }
143 }
144
145 #[doc(alias = "g_filename_from_uri")]
filename_from_uri(uri: &str) -> Result<(std::path::PathBuf, Option<GString>), Error>146 pub fn filename_from_uri(uri: &str) -> Result<(std::path::PathBuf, Option<GString>), Error> {
147 #[cfg(not(windows))]
148 use ffi::g_filename_from_uri;
149 #[cfg(windows)]
150 use ffi::g_filename_from_uri_utf8 as g_filename_from_uri;
151
152 unsafe {
153 let mut hostname = ptr::null_mut();
154 let mut error = ptr::null_mut();
155 let ret = g_filename_from_uri(uri.to_glib_none().0, &mut hostname, &mut error);
156 if error.is_null() {
157 Ok((from_glib_full(ret), from_glib_full(hostname)))
158 } else {
159 Err(from_glib_full(error))
160 }
161 }
162 }
163
164 #[doc(alias = "g_find_program_in_path")]
find_program_in_path<P: AsRef<Path>>(program: P) -> Option<PathBuf>165 pub fn find_program_in_path<P: AsRef<Path>>(program: P) -> Option<PathBuf> {
166 #[cfg(not(all(windows, target_arch = "x86")))]
167 use ffi::g_find_program_in_path;
168 #[cfg(all(windows, target_arch = "x86"))]
169 use ffi::g_find_program_in_path_utf8 as g_find_program_in_path;
170
171 unsafe { from_glib_full(g_find_program_in_path(program.as_ref().to_glib_none().0)) }
172 }
173
174 #[doc(alias = "g_get_home_dir")]
175 #[doc(alias = "get_home_dir")]
home_dir() -> std::path::PathBuf176 pub fn home_dir() -> std::path::PathBuf {
177 #[cfg(not(all(windows, target_arch = "x86")))]
178 use ffi::g_get_home_dir;
179 #[cfg(all(windows, target_arch = "x86"))]
180 use ffi::g_get_home_dir_utf8 as g_get_home_dir;
181
182 unsafe { from_glib_none(g_get_home_dir()) }
183 }
184
185 #[doc(alias = "g_get_tmp_dir")]
186 #[doc(alias = "get_tmp_dir")]
tmp_dir() -> std::path::PathBuf187 pub fn tmp_dir() -> std::path::PathBuf {
188 #[cfg(not(all(windows, target_arch = "x86")))]
189 use ffi::g_get_tmp_dir;
190 #[cfg(all(windows, target_arch = "x86"))]
191 use ffi::g_get_tmp_dir_utf8 as g_get_tmp_dir;
192
193 unsafe { from_glib_none(g_get_tmp_dir()) }
194 }
195
196 #[doc(alias = "g_mkstemp")]
mkstemp<P: AsRef<std::path::Path>>(tmpl: P) -> i32197 pub fn mkstemp<P: AsRef<std::path::Path>>(tmpl: P) -> i32 {
198 #[cfg(not(windows))]
199 use ffi::g_mkstemp;
200 #[cfg(windows)]
201 use ffi::g_mkstemp_utf8 as g_mkstemp;
202
203 unsafe { g_mkstemp(tmpl.as_ref().to_glib_none().0) }
204 }
205
is_canonical_pspec_name(name: &str) -> bool206 pub fn is_canonical_pspec_name(name: &str) -> bool {
207 name.as_bytes().iter().enumerate().all(|(i, c)| {
208 i != 0 && (*c >= b'0' && *c <= b'9' || *c == b'-')
209 || (*c >= b'A' && *c <= b'Z')
210 || (*c >= b'a' && *c <= b'z')
211 })
212 }
213
214 #[doc(alias = "g_uri_escape_string")]
uri_escape_string( unescaped: &str, reserved_chars_allowed: Option<&str>, allow_utf8: bool, ) -> crate::GString215 pub fn uri_escape_string(
216 unescaped: &str,
217 reserved_chars_allowed: Option<&str>,
218 allow_utf8: bool,
219 ) -> crate::GString {
220 unsafe {
221 from_glib_full(ffi::g_uri_escape_string(
222 unescaped.to_glib_none().0,
223 reserved_chars_allowed.to_glib_none().0,
224 allow_utf8.into_glib(),
225 ))
226 }
227 }
228
229 #[doc(alias = "g_uri_unescape_string")]
uri_unescape_string( escaped_string: &str, illegal_characters: Option<&str>, ) -> Option<crate::GString>230 pub fn uri_unescape_string(
231 escaped_string: &str,
232 illegal_characters: Option<&str>,
233 ) -> Option<crate::GString> {
234 unsafe {
235 from_glib_full(ffi::g_uri_unescape_string(
236 escaped_string.to_glib_none().0,
237 illegal_characters.to_glib_none().0,
238 ))
239 }
240 }
241
242 #[doc(alias = "g_uri_parse_scheme")]
uri_parse_scheme(uri: &str) -> Option<crate::GString>243 pub fn uri_parse_scheme(uri: &str) -> Option<crate::GString> {
244 unsafe { from_glib_full(ffi::g_uri_parse_scheme(uri.to_glib_none().0)) }
245 }
246
247 #[doc(alias = "g_uri_unescape_segment")]
uri_unescape_segment( escaped_string: Option<&str>, escaped_string_end: Option<&str>, illegal_characters: Option<&str>, ) -> Option<crate::GString>248 pub fn uri_unescape_segment(
249 escaped_string: Option<&str>,
250 escaped_string_end: Option<&str>,
251 illegal_characters: Option<&str>,
252 ) -> Option<crate::GString> {
253 unsafe {
254 from_glib_full(ffi::g_uri_unescape_segment(
255 escaped_string.to_glib_none().0,
256 escaped_string_end.to_glib_none().0,
257 illegal_characters.to_glib_none().0,
258 ))
259 }
260 }
261
262 #[cfg(test)]
263 mod tests {
264 use std::env;
265 use std::sync::Mutex;
266
267 //Mutex to prevent run environment tests parallel
268 static LOCK: once_cell::sync::Lazy<Mutex<()>> = once_cell::sync::Lazy::new(|| Mutex::new(()));
269
270 const VAR_NAME: &str = "function_environment_test";
271
check_getenv(val: &str)272 fn check_getenv(val: &str) {
273 let _data = LOCK.lock().unwrap();
274
275 env::set_var(VAR_NAME, val);
276 assert_eq!(env::var_os(VAR_NAME), Some(val.into()));
277 assert_eq!(crate::getenv(VAR_NAME), Some(val.into()));
278
279 let environ = crate::environ();
280 assert_eq!(crate::environ_getenv(&environ, VAR_NAME), Some(val.into()));
281 }
282
check_setenv(val: &str)283 fn check_setenv(val: &str) {
284 let _data = LOCK.lock().unwrap();
285
286 crate::setenv(VAR_NAME, val, true).unwrap();
287 assert_eq!(env::var_os(VAR_NAME), Some(val.into()));
288 }
289
290 #[test]
getenv()291 fn getenv() {
292 check_getenv("Test");
293 check_getenv("Тест"); // "Test" in Russian
294 }
295
296 #[test]
setenv()297 fn setenv() {
298 check_setenv("Test");
299 check_setenv("Тест"); // "Test" in Russian
300 }
301
302 #[test]
test_filename_from_uri()303 fn test_filename_from_uri() {
304 use crate::GString;
305 use std::path::PathBuf;
306 let uri: GString = "file:///foo/bar.txt".into();
307 if let Ok((filename, hostname)) = crate::filename_from_uri(&uri) {
308 assert_eq!(filename, PathBuf::from(r"/foo/bar.txt"));
309 assert_eq!(hostname, None);
310 } else {
311 unreachable!();
312 }
313
314 let uri: GString = "file://host/foo/bar.txt".into();
315 if let Ok((filename, hostname)) = crate::filename_from_uri(&uri) {
316 assert_eq!(filename, PathBuf::from(r"/foo/bar.txt"));
317 assert_eq!(hostname, Some(GString::from("host")));
318 } else {
319 unreachable!();
320 }
321 }
322
323 #[test]
test_uri_parsing()324 fn test_uri_parsing() {
325 use crate::GString;
326 assert_eq!(
327 crate::uri_parse_scheme("foo://bar"),
328 Some(GString::from("foo"))
329 );
330 assert_eq!(crate::uri_parse_scheme("foo"), None);
331
332 let escaped = crate::uri_escape_string("&foo", None, true);
333 assert_eq!(escaped, GString::from("%26foo"));
334
335 let unescaped = crate::uri_unescape_string(escaped.as_str(), None);
336 assert_eq!(unescaped, Some(GString::from("&foo")));
337
338 assert_eq!(
339 crate::uri_unescape_segment(Some("/foo"), None, None),
340 Some(GString::from("/foo"))
341 );
342 assert_eq!(crate::uri_unescape_segment(Some("/foo%"), None, None), None);
343 }
344 }
345