glib/key_file.rs
1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::{mem, path, ptr};
4
5use crate::{ffi, translate::*, Error, GString, GStringPtr, KeyFile, KeyFileFlags, PtrSlice};
6
7impl KeyFile {
8 /// Writes the contents of @self to @filename using
9 /// [`file_set_contents()`][crate::file_set_contents()].
10 ///
11 /// If you need stricter guarantees about durability of
12 /// the written file than are provided by [`file_set_contents()`][crate::file_set_contents()], use
13 /// [`file_set_contents_full()`][crate::file_set_contents_full()] with the return value of
14 /// [`to_data()`][Self::to_data()].
15 ///
16 /// This function can fail for any of the reasons that
17 /// [`file_set_contents()`][crate::file_set_contents()] may fail.
18 /// ## `filename`
19 /// the name of the file to write to
20 ///
21 /// # Returns
22 ///
23 /// true if successful, false otherwise
24 // rustdoc-stripper-ignore-next-stop
25 /// Writes the contents of @self to @filename using
26 /// [`file_set_contents()`][crate::file_set_contents()].
27 ///
28 /// If you need stricter guarantees about durability of
29 /// the written file than are provided by [`file_set_contents()`][crate::file_set_contents()], use
30 /// [`file_set_contents_full()`][crate::file_set_contents_full()] with the return value of
31 /// [`to_data()`][Self::to_data()].
32 ///
33 /// This function can fail for any of the reasons that
34 /// [`file_set_contents()`][crate::file_set_contents()] may fail.
35 /// ## `filename`
36 /// the name of the file to write to
37 ///
38 /// # Returns
39 ///
40 /// true if successful, false otherwise
41 #[doc(alias = "g_key_file_save_to_file")]
42 pub fn save_to_file<T: AsRef<std::path::Path>>(&self, filename: T) -> Result<(), Error> {
43 unsafe {
44 let mut error = ptr::null_mut();
45 let _ = ffi::g_key_file_save_to_file(
46 self.to_glib_none().0,
47 filename.as_ref().to_glib_none().0,
48 &mut error,
49 );
50 if error.is_null() {
51 Ok(())
52 } else {
53 Err(from_glib_full(error))
54 }
55 }
56 }
57
58 /// Looks for a key file named @file in the paths returned from
59 /// [`user_data_dir()`][crate::user_data_dir()] and [`system_data_dirs()`][crate::system_data_dirs()].
60 ///
61 /// The search algorithm from [`load_from_dirs()`][Self::load_from_dirs()] is used. If
62 /// @file is found, it’s loaded into @self and its full path is returned in
63 /// @full_path.
64 ///
65 /// If the file could not be loaded then either a [`FileError`][crate::FileError] or
66 /// [`KeyFileError`][crate::KeyFileError] is returned.
67 /// ## `file`
68 /// a relative path to a filename to open and parse
69 /// ## `flags`
70 /// flags from [`KeyFileFlags`][crate::KeyFileFlags]
71 ///
72 /// # Returns
73 ///
74 /// true if a key file could be loaded, false otherwise
75 ///
76 /// ## `full_path`
77 /// return location for a string
78 /// containing the full path of the file, or `NULL` to ignore
79 // rustdoc-stripper-ignore-next-stop
80 /// Looks for a key file named @file in the paths returned from
81 /// [`user_data_dir()`][crate::user_data_dir()] and [`system_data_dirs()`][crate::system_data_dirs()].
82 ///
83 /// The search algorithm from [`load_from_dirs()`][Self::load_from_dirs()] is used. If
84 /// @file is found, it’s loaded into @self and its full path is returned in
85 /// @full_path.
86 ///
87 /// If the file could not be loaded then either a [`FileError`][crate::FileError] or
88 /// [`KeyFileError`][crate::KeyFileError] is returned.
89 /// ## `file`
90 /// a relative path to a filename to open and parse
91 /// ## `flags`
92 /// flags from [`KeyFileFlags`][crate::KeyFileFlags]
93 ///
94 /// # Returns
95 ///
96 /// true if a key file could be loaded, false otherwise
97 ///
98 /// ## `full_path`
99 /// return location for a string
100 /// containing the full path of the file, or `NULL` to ignore
101 #[doc(alias = "g_key_file_load_from_data_dirs")]
102 pub fn load_from_data_dirs<T: AsRef<std::path::Path>>(
103 &self,
104 file: T,
105 flags: KeyFileFlags,
106 ) -> Result<path::PathBuf, Error> {
107 unsafe {
108 let mut error = ptr::null_mut();
109 let mut full_path: *mut libc::c_char = ptr::null_mut();
110 let _ = ffi::g_key_file_load_from_data_dirs(
111 self.to_glib_none().0,
112 file.as_ref().to_glib_none().0,
113 &mut full_path,
114 flags.into_glib(),
115 &mut error,
116 );
117 if error.is_null() {
118 let path: GString = from_glib_full(full_path);
119 Ok(path::PathBuf::from(&path))
120 } else {
121 Err(from_glib_full(error))
122 }
123 }
124 }
125
126 /// Looks for a key file named @file in the paths specified in @search_dirs,
127 /// loads the file into @self and returns the file’s full path in @full_path.
128 ///
129 /// @search_dirs are checked in the order listed in the array, with the highest
130 /// priority directory listed first. Within each directory, @file is looked for.
131 /// If it’s not found, `-` characters in @file are progressively replaced with
132 /// directory separators to search subdirectories of the search directory. If the
133 /// file has not been found after all `-` characters have been replaced, the next
134 /// search directory in @search_dirs is checked.
135 ///
136 /// If the file could not be found in any of the @search_dirs,
137 /// [error@GLib.KeyFileError.NOT_FOUND] is returned. If
138 /// the file is found but the OS returns an error when opening or reading the
139 /// file, a [`FileError`][crate::FileError] is returned. If there is a problem parsing the
140 /// file, a [`KeyFileError`][crate::KeyFileError] is returned.
141 /// ## `file`
142 /// a relative path to a filename to open and parse
143 /// ## `search_dirs`
144 /// `NULL`-terminated
145 /// array of directories to search
146 /// ## `flags`
147 /// flags from [`KeyFileFlags`][crate::KeyFileFlags]
148 ///
149 /// # Returns
150 ///
151 /// true if a key file could be loaded, false otherwise
152 ///
153 /// ## `full_path`
154 /// return location for a string
155 /// containing the full path of the file, or `NULL` to ignore
156 // rustdoc-stripper-ignore-next-stop
157 /// Looks for a key file named @file in the paths specified in @search_dirs,
158 /// loads the file into @self and returns the file’s full path in @full_path.
159 ///
160 /// @search_dirs are checked in the order listed in the array, with the highest
161 /// priority directory listed first. Within each directory, @file is looked for.
162 /// If it’s not found, `-` characters in @file are progressively replaced with
163 /// directory separators to search subdirectories of the search directory. If the
164 /// file has not been found after all `-` characters have been replaced, the next
165 /// search directory in @search_dirs is checked.
166 ///
167 /// If the file could not be found in any of the @search_dirs,
168 /// [error@GLib.KeyFileError.NOT_FOUND] is returned. If
169 /// the file is found but the OS returns an error when opening or reading the
170 /// file, a [`FileError`][crate::FileError] is returned. If there is a problem parsing the
171 /// file, a [`KeyFileError`][crate::KeyFileError] is returned.
172 /// ## `file`
173 /// a relative path to a filename to open and parse
174 /// ## `search_dirs`
175 /// `NULL`-terminated
176 /// array of directories to search
177 /// ## `flags`
178 /// flags from [`KeyFileFlags`][crate::KeyFileFlags]
179 ///
180 /// # Returns
181 ///
182 /// true if a key file could be loaded, false otherwise
183 ///
184 /// ## `full_path`
185 /// return location for a string
186 /// containing the full path of the file, or `NULL` to ignore
187 #[doc(alias = "g_key_file_load_from_dirs")]
188 pub fn load_from_dirs<T: AsRef<std::path::Path>, U: AsRef<std::path::Path>>(
189 &self,
190 file: T,
191 search_dirs: &[U],
192 flags: KeyFileFlags,
193 ) -> Result<path::PathBuf, Error> {
194 unsafe {
195 let search_dirs: Vec<&std::path::Path> =
196 search_dirs.iter().map(AsRef::as_ref).collect();
197 let mut error = ptr::null_mut();
198 let mut full_path: *mut libc::c_char = ptr::null_mut();
199 let _ = ffi::g_key_file_load_from_dirs(
200 self.to_glib_none().0,
201 file.as_ref().to_glib_none().0,
202 search_dirs.to_glib_none().0,
203 &mut full_path,
204 flags.into_glib(),
205 &mut error,
206 );
207 if error.is_null() {
208 let path: GString = from_glib_full(full_path);
209 Ok(path::PathBuf::from(&path))
210 } else {
211 Err(from_glib_full(error))
212 }
213 }
214 }
215
216 /// Outputs @self as a string.
217 ///
218 /// Note that this function never reports an error.
219 ///
220 /// # Returns
221 ///
222 /// a newly allocated string holding the contents of the key file
223 ///
224 /// ## `length`
225 /// return location for the length of the
226 /// returned string, or `NULL` to ignore
227 #[doc(alias = "g_key_file_to_data")]
228 pub fn to_data(&self) -> GString {
229 unsafe {
230 let ret =
231 ffi::g_key_file_to_data(self.to_glib_none().0, ptr::null_mut(), ptr::null_mut());
232 from_glib_full(ret)
233 }
234 }
235
236 /// Returns all groups in the key file loaded with @self.
237 ///
238 /// The array of returned groups will be `NULL`-terminated, so
239 /// @length may optionally be `NULL`.
240 ///
241 /// # Returns
242 ///
243 /// a newly-allocated
244 /// `NULL`-terminated array of strings. Use `strfreev()` to free it.
245 ///
246 /// ## `length`
247 /// return location for the number of returned groups,
248 /// or `NULL` to ignore
249 // rustdoc-stripper-ignore-next-stop
250 /// Returns all groups in the key file loaded with @self.
251 ///
252 /// The array of returned groups will be `NULL`-terminated, so
253 /// @length may optionally be `NULL`.
254 ///
255 /// # Returns
256 ///
257 /// a newly-allocated
258 /// `NULL`-terminated array of strings. Use `strfreev()` to free it.
259 ///
260 /// ## `length`
261 /// return location for the number of returned groups,
262 /// or `NULL` to ignore
263 #[doc(alias = "g_key_file_get_groups")]
264 #[doc(alias = "get_groups")]
265 pub fn groups(&self) -> PtrSlice<GStringPtr> {
266 unsafe {
267 let mut length = mem::MaybeUninit::uninit();
268 let ret = ffi::g_key_file_get_groups(self.to_glib_none().0, length.as_mut_ptr());
269 FromGlibContainer::from_glib_full_num(ret, length.assume_init() as _)
270 }
271 }
272
273 /// Returns all keys for the group name @group_name.
274 ///
275 /// The array of returned keys will be `NULL`-terminated, so @length may
276 /// optionally be `NULL`. If the @group_name cannot be found,
277 /// [error@GLib.KeyFileError.GROUP_NOT_FOUND] is returned.
278 /// ## `group_name`
279 /// a group name
280 ///
281 /// # Returns
282 ///
283 /// a newly-allocated
284 /// `NULL`-terminated array of strings. Use `strfreev()` to free it.
285 ///
286 /// ## `length`
287 /// return location for the number of keys returned,
288 /// or `NULL` to ignore
289 // rustdoc-stripper-ignore-next-stop
290 /// Returns all keys for the group name @group_name.
291 ///
292 /// The array of returned keys will be `NULL`-terminated, so @length may
293 /// optionally be `NULL`. If the @group_name cannot be found,
294 /// [error@GLib.KeyFileError.GROUP_NOT_FOUND] is returned.
295 /// ## `group_name`
296 /// a group name
297 ///
298 /// # Returns
299 ///
300 /// a newly-allocated
301 /// `NULL`-terminated array of strings. Use `strfreev()` to free it.
302 ///
303 /// ## `length`
304 /// return location for the number of keys returned,
305 /// or `NULL` to ignore
306 #[doc(alias = "g_key_file_get_keys")]
307 #[doc(alias = "get_keys")]
308 pub fn keys(&self, group_name: &str) -> Result<PtrSlice<GStringPtr>, crate::Error> {
309 unsafe {
310 let mut length = mem::MaybeUninit::uninit();
311 let mut error = ptr::null_mut();
312 let ret = ffi::g_key_file_get_keys(
313 self.to_glib_none().0,
314 group_name.to_glib_none().0,
315 length.as_mut_ptr(),
316 &mut error,
317 );
318 if error.is_null() {
319 Ok(FromGlibContainer::from_glib_full_num(
320 ret,
321 length.assume_init() as _,
322 ))
323 } else {
324 Err(from_glib_full(error))
325 }
326 }
327 }
328
329 /// Returns the value associated with @key under @group_name as a
330 /// boolean.
331 ///
332 /// If @key cannot be found then [error@GLib.KeyFileError.KEY_NOT_FOUND] is
333 /// returned. Likewise, if the value associated with @key cannot be interpreted
334 /// as a boolean then [error@GLib.KeyFileError.INVALID_VALUE] is returned.
335 /// ## `group_name`
336 /// a group name
337 /// ## `key`
338 /// a key
339 ///
340 /// # Returns
341 ///
342 /// the value associated with the key as a boolean,
343 /// or false if the key was not found or could not be parsed.
344 // rustdoc-stripper-ignore-next-stop
345 /// Returns the value associated with @key under @group_name as a
346 /// boolean.
347 ///
348 /// If @key cannot be found then [error@GLib.KeyFileError.KEY_NOT_FOUND] is
349 /// returned. Likewise, if the value associated with @key cannot be interpreted
350 /// as a boolean then [error@GLib.KeyFileError.INVALID_VALUE] is returned.
351 /// ## `group_name`
352 /// a group name
353 /// ## `key`
354 /// a key
355 ///
356 /// # Returns
357 ///
358 /// the value associated with the key as a boolean,
359 /// or false if the key was not found or could not be parsed.
360 #[doc(alias = "g_key_file_get_boolean")]
361 #[doc(alias = "get_boolean")]
362 pub fn boolean(&self, group_name: &str, key: &str) -> Result<bool, Error> {
363 unsafe {
364 let mut error = ptr::null_mut();
365 let ret = ffi::g_key_file_get_boolean(
366 self.to_glib_none().0,
367 group_name.to_glib_none().0,
368 key.to_glib_none().0,
369 &mut error,
370 );
371 if error.is_null() {
372 Ok(from_glib(ret))
373 } else {
374 Err(from_glib_full(error))
375 }
376 }
377 }
378
379 /// Looks whether the key file has the key @key in the group
380 /// @group_name.
381 ///
382 /// Note that this function does not follow the rules for [`Error`][crate::Error]
383 /// strictly;
384 /// the return value both carries meaning and signals an error. To use
385 /// this function, you must pass a [`Error`][crate::Error] pointer in @error, and
386 /// check whether it is not `NULL` to see if an error occurred.
387 ///
388 /// Language bindings should use [`value()`][Self::value()] to test whether
389 /// a key exists.
390 /// ## `group_name`
391 /// a group name
392 /// ## `key`
393 /// a key name
394 ///
395 /// # Returns
396 ///
397 /// true if @key is a part of @group_name, false otherwise
398 // rustdoc-stripper-ignore-next-stop
399 /// Looks whether the key file has the key @key in the group
400 /// @group_name.
401 ///
402 /// Note that this function does not follow the rules for [`Error`][crate::Error]
403 /// strictly;
404 /// the return value both carries meaning and signals an error. To use
405 /// this function, you must pass a [`Error`][crate::Error] pointer in @error, and
406 /// check whether it is not `NULL` to see if an error occurred.
407 ///
408 /// Language bindings should use [`value()`][Self::value()] to test whether
409 /// a key exists.
410 /// ## `group_name`
411 /// a group name
412 /// ## `key`
413 /// a key name
414 ///
415 /// # Returns
416 ///
417 /// true if @key is a part of @group_name, false otherwise
418 #[doc(alias = "g_key_file_has_key")]
419 pub fn has_key(&self, group_name: &str, key: &str) -> Result<bool, Error> {
420 unsafe {
421 let mut error = ptr::null_mut();
422 let ret = ffi::g_key_file_has_key(
423 self.to_glib_none().0,
424 group_name.to_glib_none().0,
425 key.to_glib_none().0,
426 &mut error,
427 );
428 if error.is_null() {
429 Ok(from_glib(ret))
430 } else {
431 Err(from_glib_full(error))
432 }
433 }
434 }
435
436 /// Returns the values associated with @key under @group_name as
437 /// booleans.
438 ///
439 /// If @key cannot be found then [error@GLib.KeyFileError.KEY_NOT_FOUND] is
440 /// returned. Likewise, if the values associated with @key cannot be interpreted
441 /// as booleans then [error@GLib.KeyFileError.INVALID_VALUE] is returned.
442 /// ## `group_name`
443 /// a group name
444 /// ## `key`
445 /// a key
446 ///
447 /// # Returns
448 ///
449 ///
450 /// the values associated with the key as a list of booleans, or `NULL` if the
451 /// key was not found or could not be parsed. The returned list of booleans
452 /// should be freed with `free()` when no longer needed.
453 // rustdoc-stripper-ignore-next-stop
454 /// Returns the values associated with @key under @group_name as
455 /// booleans.
456 ///
457 /// If @key cannot be found then [error@GLib.KeyFileError.KEY_NOT_FOUND] is
458 /// returned. Likewise, if the values associated with @key cannot be interpreted
459 /// as booleans then [error@GLib.KeyFileError.INVALID_VALUE] is returned.
460 /// ## `group_name`
461 /// a group name
462 /// ## `key`
463 /// a key
464 ///
465 /// # Returns
466 ///
467 ///
468 /// the values associated with the key as a list of booleans, or `NULL` if the
469 /// key was not found or could not be parsed. The returned list of booleans
470 /// should be freed with `free()` when no longer needed.
471 #[doc(alias = "g_key_file_get_boolean_list")]
472 #[doc(alias = "get_boolean_list")]
473 pub fn boolean_list(&self, group_name: &str, key: &str) -> Result<Vec<bool>, Error> {
474 unsafe {
475 let mut length = mem::MaybeUninit::uninit();
476 let mut error = ptr::null_mut();
477 let ret = ffi::g_key_file_get_boolean_list(
478 self.to_glib_none().0,
479 group_name.to_glib_none().0,
480 key.to_glib_none().0,
481 length.as_mut_ptr(),
482 &mut error,
483 );
484 if !error.is_null() {
485 return Err(from_glib_full(error));
486 }
487 Ok(FromGlibContainer::from_glib_container_num(
488 ret,
489 length.assume_init() as _,
490 ))
491 }
492 }
493
494 /// Returns the string value associated with @key under @group_name.
495 ///
496 /// Unlike [`value()`][Self::value()], this function handles escape
497 /// sequences like `\s`.
498 ///
499 /// If the key cannot be found, [error@GLib.KeyFileError.KEY_NOT_FOUND] is
500 /// returned. If the @group_name cannot be found,
501 /// [error@GLib.KeyFileError.GROUP_NOT_FOUND] is returned.
502 /// ## `group_name`
503 /// a group name
504 /// ## `key`
505 /// a key
506 ///
507 /// # Returns
508 ///
509 /// a newly allocated string or `NULL` if the specified
510 /// key cannot be found.
511 // rustdoc-stripper-ignore-next-stop
512 /// Returns the string value associated with @key under @group_name.
513 ///
514 /// Unlike [`value()`][Self::value()], this function handles escape
515 /// sequences like `\s`.
516 ///
517 /// If the key cannot be found, [error@GLib.KeyFileError.KEY_NOT_FOUND] is
518 /// returned. If the @group_name cannot be found,
519 /// [error@GLib.KeyFileError.GROUP_NOT_FOUND] is returned.
520 /// ## `group_name`
521 /// a group name
522 /// ## `key`
523 /// a key
524 ///
525 /// # Returns
526 ///
527 /// a newly allocated string or `NULL` if the specified
528 /// key cannot be found.
529 #[doc(alias = "g_key_file_get_string")]
530 #[doc(alias = "get_string")]
531 pub fn string(&self, group_name: &str, key: &str) -> Result<GString, Error> {
532 unsafe {
533 let mut error = ptr::null_mut();
534 let ret = ffi::g_key_file_get_string(
535 self.to_glib_none().0,
536 group_name.to_glib_none().0,
537 key.to_glib_none().0,
538 &mut error,
539 );
540 if error.is_null() {
541 Ok(from_glib_full(ret))
542 } else {
543 ffi::g_free(ret as *mut _);
544 Err(from_glib_full(error))
545 }
546 }
547 }
548
549 /// Returns the values associated with @key under @group_name.
550 ///
551 /// If the key cannot be found, [error@GLib.KeyFileError.KEY_NOT_FOUND] is
552 /// returned. If the @group_name cannot be found,
553 /// [error@GLib.KeyFileError.GROUP_NOT_FOUND] is returned.
554 /// ## `group_name`
555 /// a group name
556 /// ## `key`
557 /// a key
558 ///
559 /// # Returns
560 ///
561 ///
562 /// a `NULL`-terminated string array or `NULL` if the specified
563 /// key cannot be found. The array should be freed with `strfreev()`.
564 // rustdoc-stripper-ignore-next-stop
565 /// Returns the values associated with @key under @group_name.
566 ///
567 /// If the key cannot be found, [error@GLib.KeyFileError.KEY_NOT_FOUND] is
568 /// returned. If the @group_name cannot be found,
569 /// [error@GLib.KeyFileError.GROUP_NOT_FOUND] is returned.
570 /// ## `group_name`
571 /// a group name
572 /// ## `key`
573 /// a key
574 ///
575 /// # Returns
576 ///
577 ///
578 /// a `NULL`-terminated string array or `NULL` if the specified
579 /// key cannot be found. The array should be freed with `strfreev()`.
580 #[doc(alias = "g_key_file_get_string_list")]
581 #[doc(alias = "get_string_list")]
582 pub fn string_list(&self, group_name: &str, key: &str) -> Result<PtrSlice<GStringPtr>, Error> {
583 unsafe {
584 let mut length = mem::MaybeUninit::uninit();
585 let mut error = ptr::null_mut();
586 let ret = ffi::g_key_file_get_string_list(
587 self.to_glib_none().0,
588 group_name.to_glib_none().0,
589 key.to_glib_none().0,
590 length.as_mut_ptr(),
591 &mut error,
592 );
593 if error.is_null() {
594 Ok(FromGlibContainer::from_glib_full_num(
595 ret,
596 length.assume_init() as _,
597 ))
598 } else {
599 ffi::g_strfreev(ret);
600 Err(from_glib_full(error))
601 }
602 }
603 }
604
605 /// Returns the value associated with @key under @group_name
606 /// translated in the given @locale if available.
607 ///
608 /// If @locale is `C` then the untranslated value is returned (since GLib 2.84).
609 ///
610 /// If @locale is `NULL` then the current locale is assumed.
611 ///
612 /// If @locale is to be non-`NULL`, or if the current locale will change over
613 /// the lifetime of the [`KeyFile`][crate::KeyFile], it must be loaded with
614 /// [flags@GLib.KeyFileFlags.KEEP_TRANSLATIONS] in order to load strings for all
615 /// locales.
616 ///
617 /// If @key cannot be found then [error@GLib.KeyFileError.KEY_NOT_FOUND] is
618 /// returned. If the value associated
619 /// with @key cannot be interpreted or no suitable translation can
620 /// be found then the untranslated value is returned.
621 /// ## `group_name`
622 /// a group name
623 /// ## `key`
624 /// a key
625 /// ## `locale`
626 /// a locale identifier or `NULL` to use the current locale
627 ///
628 /// # Returns
629 ///
630 /// a newly allocated string or `NULL` if the specified
631 /// key cannot be found.
632 // rustdoc-stripper-ignore-next-stop
633 /// Returns the value associated with @key under @group_name
634 /// translated in the given @locale if available.
635 ///
636 /// If @locale is `C` then the untranslated value is returned (since GLib 2.84).
637 ///
638 /// If @locale is `NULL` then the current locale is assumed.
639 ///
640 /// If @locale is to be non-`NULL`, or if the current locale will change over
641 /// the lifetime of the [`KeyFile`][crate::KeyFile], it must be loaded with
642 /// [flags@GLib.KeyFileFlags.KEEP_TRANSLATIONS] in order to load strings for all
643 /// locales.
644 ///
645 /// If @key cannot be found then [error@GLib.KeyFileError.KEY_NOT_FOUND] is
646 /// returned. If the value associated
647 /// with @key cannot be interpreted or no suitable translation can
648 /// be found then the untranslated value is returned.
649 /// ## `group_name`
650 /// a group name
651 /// ## `key`
652 /// a key
653 /// ## `locale`
654 /// a locale identifier or `NULL` to use the current locale
655 ///
656 /// # Returns
657 ///
658 /// a newly allocated string or `NULL` if the specified
659 /// key cannot be found.
660 #[doc(alias = "g_key_file_get_locale_string")]
661 #[doc(alias = "get_locale_string")]
662 pub fn locale_string(
663 &self,
664 group_name: &str,
665 key: &str,
666 locale: Option<&str>,
667 ) -> Result<GString, Error> {
668 unsafe {
669 let mut error = ptr::null_mut();
670 let ret = ffi::g_key_file_get_locale_string(
671 self.to_glib_none().0,
672 group_name.to_glib_none().0,
673 key.to_glib_none().0,
674 locale.to_glib_none().0,
675 &mut error,
676 );
677 if error.is_null() {
678 Ok(from_glib_full(ret))
679 } else {
680 ffi::g_free(ret as *mut _);
681 Err(from_glib_full(error))
682 }
683 }
684 }
685
686 /// Returns the values associated with @key under @group_name
687 /// translated in the given @locale if available.
688 ///
689 /// If @locale is `C` then the untranslated value is returned (since GLib 2.84).
690 ///
691 /// If @locale is `NULL` then the current locale is assumed.
692 ///
693 /// If @locale is to be non-`NULL`, or if the current locale will change over
694 /// the lifetime of the [`KeyFile`][crate::KeyFile], it must be loaded with
695 /// [flags@GLib.KeyFileFlags.KEEP_TRANSLATIONS] in order to load strings for all
696 /// locales.
697 ///
698 /// If @key cannot be found then [error@GLib.KeyFileError.KEY_NOT_FOUND] is
699 /// returned. If the values associated
700 /// with @key cannot be interpreted or no suitable translations
701 /// can be found then the untranslated values are returned. The
702 /// returned array is `NULL`-terminated, so @length may optionally
703 /// be `NULL`.
704 /// ## `group_name`
705 /// a group name
706 /// ## `key`
707 /// a key
708 /// ## `locale`
709 /// a locale identifier or `NULL` to use the current locale
710 ///
711 /// # Returns
712 ///
713 ///
714 /// a newly allocated `NULL`-terminated string array or `NULL` if the key
715 /// isn’t found. The string array should be freed with `strfreev()`.
716 // rustdoc-stripper-ignore-next-stop
717 /// Returns the values associated with @key under @group_name
718 /// translated in the given @locale if available.
719 ///
720 /// If @locale is `C` then the untranslated value is returned (since GLib 2.84).
721 ///
722 /// If @locale is `NULL` then the current locale is assumed.
723 ///
724 /// If @locale is to be non-`NULL`, or if the current locale will change over
725 /// the lifetime of the [`KeyFile`][crate::KeyFile], it must be loaded with
726 /// [flags@GLib.KeyFileFlags.KEEP_TRANSLATIONS] in order to load strings for all
727 /// locales.
728 ///
729 /// If @key cannot be found then [error@GLib.KeyFileError.KEY_NOT_FOUND] is
730 /// returned. If the values associated
731 /// with @key cannot be interpreted or no suitable translations
732 /// can be found then the untranslated values are returned. The
733 /// returned array is `NULL`-terminated, so @length may optionally
734 /// be `NULL`.
735 /// ## `group_name`
736 /// a group name
737 /// ## `key`
738 /// a key
739 /// ## `locale`
740 /// a locale identifier or `NULL` to use the current locale
741 ///
742 /// # Returns
743 ///
744 ///
745 /// a newly allocated `NULL`-terminated string array or `NULL` if the key
746 /// isn’t found. The string array should be freed with `strfreev()`.
747 #[doc(alias = "g_key_file_get_locale_string_list")]
748 #[doc(alias = "get_locale_string_list")]
749 pub fn locale_string_list(
750 &self,
751 group_name: &str,
752 key: &str,
753 locale: Option<&str>,
754 ) -> Result<PtrSlice<GStringPtr>, Error> {
755 unsafe {
756 let mut length = mem::MaybeUninit::uninit();
757 let mut error = ptr::null_mut();
758 let ret = ffi::g_key_file_get_locale_string_list(
759 self.to_glib_none().0,
760 group_name.to_glib_none().0,
761 key.to_glib_none().0,
762 locale.to_glib_none().0,
763 length.as_mut_ptr(),
764 &mut error,
765 );
766 if error.is_null() {
767 Ok(FromGlibContainer::from_glib_full_num(
768 ret,
769 length.assume_init() as _,
770 ))
771 } else {
772 ffi::g_strfreev(ret);
773 Err(from_glib_full(error))
774 }
775 }
776 }
777}