gio/auto/file.rs
1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// DO NOT EDIT
4
5use crate::{
6 AppInfo, AsyncResult, Cancellable, DriveStartFlags, FileAttributeInfoList, FileCopyFlags,
7 FileCreateFlags, FileEnumerator, FileIOStream, FileInfo, FileInputStream, FileMeasureFlags,
8 FileMonitor, FileMonitorFlags, FileOutputStream, FileQueryInfoFlags, FileType, Mount,
9 MountMountFlags, MountOperation, MountUnmountFlags, ffi,
10};
11use glib::{prelude::*, translate::*};
12use std::{boxed::Box as Box_, pin::Pin};
13
14glib::wrapper! {
15 /// `GFile` is a high level abstraction for manipulating files on a
16 /// virtual file system. `GFile`s are lightweight, immutable objects
17 /// that do no I/O upon creation. It is necessary to understand that
18 /// `GFile` objects do not represent files, merely an identifier for a
19 /// file. All file content I/O is implemented as streaming operations
20 /// (see [`InputStream`][crate::InputStream] and [`OutputStream`][crate::OutputStream]).
21 ///
22 /// To construct a `GFile`, you can use:
23 ///
24 /// - [`for_path()`][Self::for_path()] if you have a path.
25 /// - [`for_uri()`][Self::for_uri()] if you have a URI.
26 /// - [`for_commandline_arg()`][Self::for_commandline_arg()] or
27 /// [`for_commandline_arg_and_cwd()`][Self::for_commandline_arg_and_cwd()] for a command line
28 /// argument.
29 /// - [`new_tmp()`][Self::new_tmp()] to create a temporary file from a template.
30 /// - [`new_tmp_async()`][Self::new_tmp_async()] to asynchronously create a temporary file.
31 /// - [`new_tmp_dir_async()`][Self::new_tmp_dir_async()] to asynchronously create a temporary
32 /// directory.
33 /// - [`for_parse_name()`][Self::for_parse_name()] from a UTF-8 string gotten from
34 /// [`FileExt::parse_name()`][crate::prelude::FileExt::parse_name()].
35 /// - `Gio::File::new_build_filename()` or [`new_build_filenamev()`][Self::new_build_filenamev()]
36 /// to create a file from path elements.
37 ///
38 /// One way to think of a `GFile` is as an abstraction of a pathname. For
39 /// normal files the system pathname is what is stored internally, but as
40 /// `GFile`s are extensible it could also be something else that corresponds
41 /// to a pathname in a userspace implementation of a filesystem.
42 ///
43 /// `GFile`s make up hierarchies of directories and files that correspond to
44 /// the files on a filesystem. You can move through the file system with
45 /// `GFile` using [`FileExt::parent()`][crate::prelude::FileExt::parent()] to get an identifier for the
46 /// parent directory, [`FileExt::child()`][crate::prelude::FileExt::child()] to get a child within a
47 /// directory, and [`FileExt::resolve_relative_path()`][crate::prelude::FileExt::resolve_relative_path()] to resolve a relative
48 /// path between two `GFile`s. There can be multiple hierarchies, so you may not
49 /// end up at the same root if you repeatedly call [`FileExt::parent()`][crate::prelude::FileExt::parent()]
50 /// on two different files.
51 ///
52 /// All `GFile`s have a basename (get with [`FileExt::basename()`][crate::prelude::FileExt::basename()]). These
53 /// names are byte strings that are used to identify the file on the filesystem
54 /// (relative to its parent directory) and there is no guarantees that they
55 /// have any particular charset encoding or even make any sense at all. If
56 /// you want to use filenames in a user interface you should use the display
57 /// name that you can get by requesting the
58 /// `G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME` attribute with
59 /// [`FileExt::query_info()`][crate::prelude::FileExt::query_info()]. This is guaranteed to be in UTF-8 and can be
60 /// used in a user interface. But always store the real basename or the `GFile`
61 /// to use to actually access the file, because there is no way to go from a
62 /// display name to the actual name.
63 ///
64 /// Using `GFile` as an identifier has the same weaknesses as using a path
65 /// in that there may be multiple aliases for the same file. For instance,
66 /// hard or soft links may cause two different `GFile`s to refer to the same
67 /// file. Other possible causes for aliases are: case insensitive filesystems,
68 /// short and long names on FAT/NTFS, or bind mounts in Linux. If you want to
69 /// check if two `GFile`s point to the same file you can query for the
70 /// `G_FILE_ATTRIBUTE_ID_FILE` attribute. Note that `GFile` does some trivial
71 /// canonicalization of pathnames passed in, so that trivial differences in
72 /// the path string used at creation (duplicated slashes, slash at end of
73 /// path, `.` or `..` path segments, etc) does not create different `GFile`s.
74 ///
75 /// Many `GFile` operations have both synchronous and asynchronous versions
76 /// to suit your application. Asynchronous versions of synchronous functions
77 /// simply have `_async()` appended to their function names. The asynchronous
78 /// I/O functions call a `callback::Gio::AsyncReadyCallback which is then used to
79 /// finalize the operation, producing a [`AsyncResult`][crate::AsyncResult] which is then
80 /// passed to the function’s matching `_finish()` operation.
81 ///
82 /// It is highly recommended to use asynchronous calls when running within a
83 /// shared main loop, such as in the main thread of an application. This avoids
84 /// I/O operations blocking other sources on the main loop from being dispatched.
85 /// Synchronous I/O operations should be performed from worker threads. See the
86 /// [introduction to asynchronous programming section](overview.html#asynchronous-programming)
87 /// for more.
88 ///
89 /// Some `GFile` operations almost always take a noticeable amount of time, and
90 /// so do not have synchronous analogs. Notable cases include:
91 ///
92 /// - [`FileExt::mount_mountable()`][crate::prelude::FileExt::mount_mountable()] to mount a mountable file.
93 /// - [`FileExt::unmount_mountable_with_operation()`][crate::prelude::FileExt::unmount_mountable_with_operation()] to unmount a mountable
94 /// file.
95 /// - [`FileExt::eject_mountable_with_operation()`][crate::prelude::FileExt::eject_mountable_with_operation()] to eject a mountable file.
96 ///
97 /// ## Entity Tags
98 ///
99 /// One notable feature of `GFile`s are entity tags, or ‘etags’ for
100 /// short. Entity tags are somewhat like a more abstract version of the
101 /// traditional mtime, and can be used to quickly determine if the file
102 /// has been modified from the version on the file system. See the
103 /// description of HTTP ETags in
104 /// [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-etag).
105 /// `GFile` Entity Tags are a very similar concept.
106 ///
107 /// # Implements
108 ///
109 /// [`FileExt`][trait@crate::prelude::FileExt], [`FileExtManual`][trait@crate::prelude::FileExtManual]
110 #[doc(alias = "GFile")]
111 pub struct File(Interface<ffi::GFile, ffi::GFileIface>);
112
113 match fn {
114 type_ => || ffi::g_file_get_type(),
115 }
116}
117
118impl File {
119 pub const NONE: Option<&'static File> = None;
120
121 //#[doc(alias = "g_file_new_build_filename")]
122 //pub fn new_build_filename(first_element: impl AsRef<std::path::Path>, : /*Unknown conversion*//*Unimplemented*/Basic: VarArgs) -> File {
123 // unsafe { TODO: call ffi:g_file_new_build_filename() }
124 //}
125
126 /// Constructs a #GFile from a vector of elements using the correct
127 /// separator for filenames.
128 ///
129 /// Using this function is equivalent to calling g_build_filenamev(),
130 /// followed by g_file_new_for_path() on the result.
131 /// ## `args`
132 /// [`None`]-terminated
133 /// array of strings containing the path elements.
134 ///
135 /// # Returns
136 ///
137 /// a new #GFile
138 #[cfg(feature = "v2_78")]
139 #[cfg_attr(docsrs, doc(cfg(feature = "v2_78")))]
140 #[doc(alias = "g_file_new_build_filenamev")]
141 pub fn new_build_filenamev(args: &[&std::path::Path]) -> File {
142 unsafe { from_glib_full(ffi::g_file_new_build_filenamev(args.to_glib_none().0)) }
143 }
144
145 /// Creates a #GFile with the given argument from the command line.
146 /// The value of @arg can be either a URI, an absolute path or a
147 /// relative path resolved relative to the current working directory.
148 /// This operation never fails, but the returned object might not
149 /// support any I/O operation if @arg points to a malformed path.
150 ///
151 /// Note that on Windows, this function expects its argument to be in
152 /// UTF-8 -- not the system code page. This means that you
153 /// should not use this function with string from argv as it is passed
154 /// to main(). g_win32_get_command_line() will return a UTF-8 version of
155 /// the commandline. #GApplication also uses UTF-8 but
156 /// g_application_command_line_create_file_for_arg() may be more useful
157 /// for you there. It is also always possible to use this function with
158 /// #GOptionContext arguments of type [`glib::OptionArg::Filename`][crate::glib::OptionArg::Filename].
159 /// ## `arg`
160 /// a command line string
161 ///
162 /// # Returns
163 ///
164 /// a new #GFile.
165 /// Free the returned object with g_object_unref().
166 #[doc(alias = "g_file_new_for_commandline_arg")]
167 #[doc(alias = "new_for_commandline_arg")]
168 pub fn for_commandline_arg(arg: impl AsRef<std::ffi::OsStr>) -> File {
169 unsafe {
170 from_glib_full(ffi::g_file_new_for_commandline_arg(
171 arg.as_ref().to_glib_none().0,
172 ))
173 }
174 }
175
176 /// Creates a #GFile with the given argument from the command line.
177 ///
178 /// This function is similar to g_file_new_for_commandline_arg() except
179 /// that it allows for passing the current working directory as an
180 /// argument instead of using the current working directory of the
181 /// process.
182 ///
183 /// This is useful if the commandline argument was given in a context
184 /// other than the invocation of the current process.
185 ///
186 /// See also g_application_command_line_create_file_for_arg().
187 /// ## `arg`
188 /// a command line string
189 /// ## `cwd`
190 /// the current working directory of the commandline
191 ///
192 /// # Returns
193 ///
194 /// a new #GFile
195 #[doc(alias = "g_file_new_for_commandline_arg_and_cwd")]
196 #[doc(alias = "new_for_commandline_arg_and_cwd")]
197 pub fn for_commandline_arg_and_cwd(
198 arg: impl AsRef<std::ffi::OsStr>,
199 cwd: impl AsRef<std::path::Path>,
200 ) -> File {
201 unsafe {
202 from_glib_full(ffi::g_file_new_for_commandline_arg_and_cwd(
203 arg.as_ref().to_glib_none().0,
204 cwd.as_ref().to_glib_none().0,
205 ))
206 }
207 }
208
209 /// Constructs a #GFile for a given path. This operation never
210 /// fails, but the returned object might not support any I/O
211 /// operation if @path is malformed.
212 /// ## `path`
213 /// a string containing a relative or absolute path.
214 /// The string must be encoded in the glib filename encoding.
215 ///
216 /// # Returns
217 ///
218 /// a new #GFile for the given @path.
219 /// Free the returned object with g_object_unref().
220 #[doc(alias = "g_file_new_for_path")]
221 #[doc(alias = "new_for_path")]
222 pub fn for_path(path: impl AsRef<std::path::Path>) -> File {
223 unsafe { from_glib_full(ffi::g_file_new_for_path(path.as_ref().to_glib_none().0)) }
224 }
225
226 /// Constructs a #GFile for a given URI. This operation never
227 /// fails, but the returned object might not support any I/O
228 /// operation if @uri is malformed or if the uri type is
229 /// not supported.
230 /// ## `uri`
231 /// a UTF-8 string containing a URI
232 ///
233 /// # Returns
234 ///
235 /// a new #GFile for the given @uri.
236 /// Free the returned object with g_object_unref().
237 #[doc(alias = "g_file_new_for_uri")]
238 #[doc(alias = "new_for_uri")]
239 pub fn for_uri(uri: &str) -> File {
240 unsafe { from_glib_full(ffi::g_file_new_for_uri(uri.to_glib_none().0)) }
241 }
242
243 /// Opens a file in the preferred directory for temporary files (as
244 /// returned by g_get_tmp_dir()) and returns a #GFile and
245 /// #GFileIOStream pointing to it.
246 ///
247 /// @tmpl should be a string in the GLib file name encoding
248 /// containing a sequence of six 'X' characters, and containing no
249 /// directory components. If it is [`None`], a default template is used.
250 ///
251 /// Unlike the other #GFile constructors, this will return [`None`] if
252 /// a temporary file could not be created.
253 /// ## `tmpl`
254 /// Template for the file
255 /// name, as in g_file_open_tmp(), or [`None`] for a default template
256 ///
257 /// # Returns
258 ///
259 /// a new #GFile.
260 /// Free the returned object with g_object_unref().
261 ///
262 /// ## `iostream`
263 /// on return, a #GFileIOStream for the created file
264 #[doc(alias = "g_file_new_tmp")]
265 pub fn new_tmp(
266 tmpl: Option<impl AsRef<std::path::Path>>,
267 ) -> Result<(File, FileIOStream), glib::Error> {
268 unsafe {
269 let mut iostream = std::ptr::null_mut();
270 let mut error = std::ptr::null_mut();
271 let ret = ffi::g_file_new_tmp(
272 tmpl.as_ref().map(|p| p.as_ref()).to_glib_none().0,
273 &mut iostream,
274 &mut error,
275 );
276 if error.is_null() {
277 Ok((from_glib_full(ret), from_glib_full(iostream)))
278 } else {
279 Err(from_glib_full(error))
280 }
281 }
282 }
283
284 /// Constructs a #GFile with the given @parse_name (i.e. something
285 /// given by g_file_get_parse_name()). This operation never fails,
286 /// but the returned object might not support any I/O operation if
287 /// the @parse_name cannot be parsed.
288 /// ## `parse_name`
289 /// a file name or path to be parsed
290 ///
291 /// # Returns
292 ///
293 /// a new #GFile.
294 #[doc(alias = "g_file_parse_name")]
295 #[doc(alias = "parse_name")]
296 pub fn for_parse_name(parse_name: &str) -> File {
297 unsafe { from_glib_full(ffi::g_file_parse_name(parse_name.to_glib_none().0)) }
298 }
299}
300
301unsafe impl Send for File {}
302unsafe impl Sync for File {}
303
304/// Trait containing all [`struct@File`] methods.
305///
306/// # Implementors
307///
308/// [`File`][struct@crate::File]
309pub trait FileExt: IsA<File> + 'static {
310 /// Gets an output stream for appending data to the file.
311 /// If the file doesn't already exist it is created.
312 ///
313 /// By default files created are generally readable by everyone,
314 /// but if you pass [`FileCreateFlags::PRIVATE`][crate::FileCreateFlags::PRIVATE] in @flags the file
315 /// will be made readable only to the current user, to the level that
316 /// is supported on the target filesystem.
317 ///
318 /// If @cancellable is not [`None`], then the operation can be cancelled
319 /// by triggering the cancellable object from another thread. If the
320 /// operation was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be
321 /// returned.
322 ///
323 /// Some file systems don't allow all file names, and may return an
324 /// [`IOErrorEnum::InvalidFilename`][crate::IOErrorEnum::InvalidFilename] error. If the file is a directory the
325 /// [`IOErrorEnum::IsDirectory`][crate::IOErrorEnum::IsDirectory] error will be returned. Other errors are
326 /// possible too, and depend on what kind of filesystem the file is on.
327 /// ## `flags`
328 /// a set of #GFileCreateFlags
329 /// ## `cancellable`
330 /// optional #GCancellable object,
331 /// [`None`] to ignore
332 ///
333 /// # Returns
334 ///
335 /// a #GFileOutputStream, or [`None`] on error.
336 /// Free the returned object with g_object_unref().
337 #[doc(alias = "g_file_append_to")]
338 fn append_to(
339 &self,
340 flags: FileCreateFlags,
341 cancellable: Option<&impl IsA<Cancellable>>,
342 ) -> Result<FileOutputStream, glib::Error> {
343 unsafe {
344 let mut error = std::ptr::null_mut();
345 let ret = ffi::g_file_append_to(
346 self.as_ref().to_glib_none().0,
347 flags.into_glib(),
348 cancellable.map(|p| p.as_ref()).to_glib_none().0,
349 &mut error,
350 );
351 if error.is_null() {
352 Ok(from_glib_full(ret))
353 } else {
354 Err(from_glib_full(error))
355 }
356 }
357 }
358
359 /// Asynchronously opens @self for appending.
360 ///
361 /// For more details, see g_file_append_to() which is
362 /// the synchronous version of this call.
363 ///
364 /// When the operation is finished, @callback will be called.
365 /// You can then call g_file_append_to_finish() to get the result
366 /// of the operation.
367 /// ## `flags`
368 /// a set of #GFileCreateFlags
369 /// ## `io_priority`
370 /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
371 /// ## `cancellable`
372 /// optional #GCancellable object,
373 /// [`None`] to ignore
374 /// ## `callback`
375 /// a #GAsyncReadyCallback
376 /// to call when the request is satisfied
377 #[doc(alias = "g_file_append_to_async")]
378 fn append_to_async<P: FnOnce(Result<FileOutputStream, glib::Error>) + 'static>(
379 &self,
380 flags: FileCreateFlags,
381 io_priority: glib::Priority,
382 cancellable: Option<&impl IsA<Cancellable>>,
383 callback: P,
384 ) {
385 let main_context = glib::MainContext::ref_thread_default();
386 let is_main_context_owner = main_context.is_owner();
387 let has_acquired_main_context = (!is_main_context_owner)
388 .then(|| main_context.acquire().ok())
389 .flatten();
390 assert!(
391 is_main_context_owner || has_acquired_main_context.is_some(),
392 "Async operations only allowed if the thread is owning the MainContext"
393 );
394
395 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
396 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
397 unsafe extern "C" fn append_to_async_trampoline<
398 P: FnOnce(Result<FileOutputStream, glib::Error>) + 'static,
399 >(
400 _source_object: *mut glib::gobject_ffi::GObject,
401 res: *mut crate::ffi::GAsyncResult,
402 user_data: glib::ffi::gpointer,
403 ) {
404 unsafe {
405 let mut error = std::ptr::null_mut();
406 let ret = ffi::g_file_append_to_finish(_source_object as *mut _, res, &mut error);
407 let result = if error.is_null() {
408 Ok(from_glib_full(ret))
409 } else {
410 Err(from_glib_full(error))
411 };
412 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
413 Box_::from_raw(user_data as *mut _);
414 let callback: P = callback.into_inner();
415 callback(result);
416 }
417 }
418 let callback = append_to_async_trampoline::<P>;
419 unsafe {
420 ffi::g_file_append_to_async(
421 self.as_ref().to_glib_none().0,
422 flags.into_glib(),
423 io_priority.into_glib(),
424 cancellable.map(|p| p.as_ref()).to_glib_none().0,
425 Some(callback),
426 Box_::into_raw(user_data) as *mut _,
427 );
428 }
429 }
430
431 fn append_to_future(
432 &self,
433 flags: FileCreateFlags,
434 io_priority: glib::Priority,
435 ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileOutputStream, glib::Error>> + 'static>>
436 {
437 Box_::pin(crate::GioFuture::new(
438 self,
439 move |obj, cancellable, send| {
440 obj.append_to_async(flags, io_priority, Some(cancellable), move |res| {
441 send.resolve(res);
442 });
443 },
444 ))
445 }
446
447 #[cfg(feature = "v2_68")]
448 #[cfg_attr(docsrs, doc(cfg(feature = "v2_68")))]
449 #[doc(alias = "g_file_build_attribute_list_for_copy")]
450 fn build_attribute_list_for_copy(
451 &self,
452 flags: FileCopyFlags,
453 cancellable: Option<&impl IsA<Cancellable>>,
454 ) -> Result<glib::GString, glib::Error> {
455 unsafe {
456 let mut error = std::ptr::null_mut();
457 let ret = ffi::g_file_build_attribute_list_for_copy(
458 self.as_ref().to_glib_none().0,
459 flags.into_glib(),
460 cancellable.map(|p| p.as_ref()).to_glib_none().0,
461 &mut error,
462 );
463 if error.is_null() {
464 Ok(from_glib_full(ret))
465 } else {
466 Err(from_glib_full(error))
467 }
468 }
469 }
470
471 #[doc(alias = "g_file_copy")]
472 fn copy(
473 &self,
474 destination: &impl IsA<File>,
475 flags: FileCopyFlags,
476 cancellable: Option<&impl IsA<Cancellable>>,
477 progress_callback: Option<&mut dyn FnMut(i64, i64)>,
478 ) -> Result<(), glib::Error> {
479 let mut progress_callback_data: Option<&mut dyn FnMut(i64, i64)> = progress_callback;
480 unsafe extern "C" fn progress_callback_func(
481 current_num_bytes: i64,
482 total_num_bytes: i64,
483 data: glib::ffi::gpointer,
484 ) {
485 unsafe {
486 let callback = data as *mut Option<&mut dyn FnMut(i64, i64)>;
487 if let Some(ref mut callback) = *callback {
488 callback(current_num_bytes, total_num_bytes)
489 } else {
490 panic!("cannot get closure...")
491 }
492 }
493 }
494 let progress_callback = if progress_callback_data.is_some() {
495 Some(progress_callback_func as _)
496 } else {
497 None
498 };
499 let super_callback0: &mut Option<&mut dyn FnMut(i64, i64)> = &mut progress_callback_data;
500 unsafe {
501 let mut error = std::ptr::null_mut();
502 let is_ok = ffi::g_file_copy(
503 self.as_ref().to_glib_none().0,
504 destination.as_ref().to_glib_none().0,
505 flags.into_glib(),
506 cancellable.map(|p| p.as_ref()).to_glib_none().0,
507 progress_callback,
508 super_callback0 as *mut _ as *mut _,
509 &mut error,
510 );
511 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
512 if error.is_null() {
513 Ok(())
514 } else {
515 Err(from_glib_full(error))
516 }
517 }
518 }
519
520 /// Copies the file attributes from @self to @destination.
521 ///
522 /// Normally only a subset of the file attributes are copied,
523 /// those that are copies in a normal file copy operation
524 /// (which for instance does not include e.g. owner). However
525 /// if [`FileCopyFlags::ALL_METADATA`][crate::FileCopyFlags::ALL_METADATA] is specified in @flags, then
526 /// all the metadata that is possible to copy is copied. This
527 /// is useful when implementing move by copy + delete source.
528 /// ## `destination`
529 /// a #GFile to copy attributes to
530 /// ## `flags`
531 /// a set of #GFileCopyFlags
532 /// ## `cancellable`
533 /// optional #GCancellable object,
534 /// [`None`] to ignore
535 ///
536 /// # Returns
537 ///
538 /// [`true`] if the attributes were copied successfully,
539 /// [`false`] otherwise.
540 #[doc(alias = "g_file_copy_attributes")]
541 fn copy_attributes(
542 &self,
543 destination: &impl IsA<File>,
544 flags: FileCopyFlags,
545 cancellable: Option<&impl IsA<Cancellable>>,
546 ) -> Result<(), glib::Error> {
547 unsafe {
548 let mut error = std::ptr::null_mut();
549 let is_ok = ffi::g_file_copy_attributes(
550 self.as_ref().to_glib_none().0,
551 destination.as_ref().to_glib_none().0,
552 flags.into_glib(),
553 cancellable.map(|p| p.as_ref()).to_glib_none().0,
554 &mut error,
555 );
556 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
557 if error.is_null() {
558 Ok(())
559 } else {
560 Err(from_glib_full(error))
561 }
562 }
563 }
564
565 /// Creates a new file and returns an output stream for writing to it.
566 /// The file must not already exist.
567 ///
568 /// By default files created are generally readable by everyone,
569 /// but if you pass [`FileCreateFlags::PRIVATE`][crate::FileCreateFlags::PRIVATE] in @flags the file
570 /// will be made readable only to the current user, to the level
571 /// that is supported on the target filesystem.
572 ///
573 /// If @cancellable is not [`None`], then the operation can be cancelled
574 /// by triggering the cancellable object from another thread. If the
575 /// operation was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be
576 /// returned.
577 ///
578 /// If a file or directory with this name already exists the
579 /// [`IOErrorEnum::Exists`][crate::IOErrorEnum::Exists] error will be returned. Some file systems don't
580 /// allow all file names, and may return an [`IOErrorEnum::InvalidFilename`][crate::IOErrorEnum::InvalidFilename]
581 /// error, and if the name is to long [`IOErrorEnum::FilenameTooLong`][crate::IOErrorEnum::FilenameTooLong] will
582 /// be returned. Other errors are possible too, and depend on what kind
583 /// of filesystem the file is on.
584 /// ## `flags`
585 /// a set of #GFileCreateFlags
586 /// ## `cancellable`
587 /// optional #GCancellable object,
588 /// [`None`] to ignore
589 ///
590 /// # Returns
591 ///
592 /// a #GFileOutputStream for the newly created
593 /// file, or [`None`] on error.
594 /// Free the returned object with g_object_unref().
595 #[doc(alias = "g_file_create")]
596 fn create(
597 &self,
598 flags: FileCreateFlags,
599 cancellable: Option<&impl IsA<Cancellable>>,
600 ) -> Result<FileOutputStream, glib::Error> {
601 unsafe {
602 let mut error = std::ptr::null_mut();
603 let ret = ffi::g_file_create(
604 self.as_ref().to_glib_none().0,
605 flags.into_glib(),
606 cancellable.map(|p| p.as_ref()).to_glib_none().0,
607 &mut error,
608 );
609 if error.is_null() {
610 Ok(from_glib_full(ret))
611 } else {
612 Err(from_glib_full(error))
613 }
614 }
615 }
616
617 /// Asynchronously creates a new file and returns an output stream
618 /// for writing to it. The file must not already exist.
619 ///
620 /// For more details, see g_file_create() which is
621 /// the synchronous version of this call.
622 ///
623 /// When the operation is finished, @callback will be called.
624 /// You can then call g_file_create_finish() to get the result
625 /// of the operation.
626 /// ## `flags`
627 /// a set of #GFileCreateFlags
628 /// ## `io_priority`
629 /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
630 /// ## `cancellable`
631 /// optional #GCancellable object,
632 /// [`None`] to ignore
633 /// ## `callback`
634 /// a #GAsyncReadyCallback
635 /// to call when the request is satisfied
636 #[doc(alias = "g_file_create_async")]
637 fn create_async<P: FnOnce(Result<FileOutputStream, glib::Error>) + 'static>(
638 &self,
639 flags: FileCreateFlags,
640 io_priority: glib::Priority,
641 cancellable: Option<&impl IsA<Cancellable>>,
642 callback: P,
643 ) {
644 let main_context = glib::MainContext::ref_thread_default();
645 let is_main_context_owner = main_context.is_owner();
646 let has_acquired_main_context = (!is_main_context_owner)
647 .then(|| main_context.acquire().ok())
648 .flatten();
649 assert!(
650 is_main_context_owner || has_acquired_main_context.is_some(),
651 "Async operations only allowed if the thread is owning the MainContext"
652 );
653
654 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
655 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
656 unsafe extern "C" fn create_async_trampoline<
657 P: FnOnce(Result<FileOutputStream, glib::Error>) + 'static,
658 >(
659 _source_object: *mut glib::gobject_ffi::GObject,
660 res: *mut crate::ffi::GAsyncResult,
661 user_data: glib::ffi::gpointer,
662 ) {
663 unsafe {
664 let mut error = std::ptr::null_mut();
665 let ret = ffi::g_file_create_finish(_source_object as *mut _, res, &mut error);
666 let result = if error.is_null() {
667 Ok(from_glib_full(ret))
668 } else {
669 Err(from_glib_full(error))
670 };
671 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
672 Box_::from_raw(user_data as *mut _);
673 let callback: P = callback.into_inner();
674 callback(result);
675 }
676 }
677 let callback = create_async_trampoline::<P>;
678 unsafe {
679 ffi::g_file_create_async(
680 self.as_ref().to_glib_none().0,
681 flags.into_glib(),
682 io_priority.into_glib(),
683 cancellable.map(|p| p.as_ref()).to_glib_none().0,
684 Some(callback),
685 Box_::into_raw(user_data) as *mut _,
686 );
687 }
688 }
689
690 fn create_future(
691 &self,
692 flags: FileCreateFlags,
693 io_priority: glib::Priority,
694 ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileOutputStream, glib::Error>> + 'static>>
695 {
696 Box_::pin(crate::GioFuture::new(
697 self,
698 move |obj, cancellable, send| {
699 obj.create_async(flags, io_priority, Some(cancellable), move |res| {
700 send.resolve(res);
701 });
702 },
703 ))
704 }
705
706 /// Creates a new file and returns a stream for reading and
707 /// writing to it. The file must not already exist.
708 ///
709 /// By default files created are generally readable by everyone,
710 /// but if you pass [`FileCreateFlags::PRIVATE`][crate::FileCreateFlags::PRIVATE] in @flags the file
711 /// will be made readable only to the current user, to the level
712 /// that is supported on the target filesystem.
713 ///
714 /// If @cancellable is not [`None`], then the operation can be cancelled
715 /// by triggering the cancellable object from another thread. If the
716 /// operation was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be
717 /// returned.
718 ///
719 /// If a file or directory with this name already exists, the
720 /// [`IOErrorEnum::Exists`][crate::IOErrorEnum::Exists] error will be returned. Some file systems don't
721 /// allow all file names, and may return an [`IOErrorEnum::InvalidFilename`][crate::IOErrorEnum::InvalidFilename]
722 /// error, and if the name is too long, [`IOErrorEnum::FilenameTooLong`][crate::IOErrorEnum::FilenameTooLong]
723 /// will be returned. Other errors are possible too, and depend on what
724 /// kind of filesystem the file is on.
725 ///
726 /// Note that in many non-local file cases read and write streams are
727 /// not supported, so make sure you really need to do read and write
728 /// streaming, rather than just opening for reading or writing.
729 /// ## `flags`
730 /// a set of #GFileCreateFlags
731 /// ## `cancellable`
732 /// optional #GCancellable object,
733 /// [`None`] to ignore
734 ///
735 /// # Returns
736 ///
737 /// a #GFileIOStream for the newly created
738 /// file, or [`None`] on error.
739 /// Free the returned object with g_object_unref().
740 #[doc(alias = "g_file_create_readwrite")]
741 fn create_readwrite(
742 &self,
743 flags: FileCreateFlags,
744 cancellable: Option<&impl IsA<Cancellable>>,
745 ) -> Result<FileIOStream, glib::Error> {
746 unsafe {
747 let mut error = std::ptr::null_mut();
748 let ret = ffi::g_file_create_readwrite(
749 self.as_ref().to_glib_none().0,
750 flags.into_glib(),
751 cancellable.map(|p| p.as_ref()).to_glib_none().0,
752 &mut error,
753 );
754 if error.is_null() {
755 Ok(from_glib_full(ret))
756 } else {
757 Err(from_glib_full(error))
758 }
759 }
760 }
761
762 /// Asynchronously creates a new file and returns a stream
763 /// for reading and writing to it. The file must not already exist.
764 ///
765 /// For more details, see g_file_create_readwrite() which is
766 /// the synchronous version of this call.
767 ///
768 /// When the operation is finished, @callback will be called.
769 /// You can then call g_file_create_readwrite_finish() to get
770 /// the result of the operation.
771 /// ## `flags`
772 /// a set of #GFileCreateFlags
773 /// ## `io_priority`
774 /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
775 /// ## `cancellable`
776 /// optional #GCancellable object,
777 /// [`None`] to ignore
778 /// ## `callback`
779 /// a #GAsyncReadyCallback
780 /// to call when the request is satisfied
781 #[doc(alias = "g_file_create_readwrite_async")]
782 fn create_readwrite_async<P: FnOnce(Result<FileIOStream, glib::Error>) + 'static>(
783 &self,
784 flags: FileCreateFlags,
785 io_priority: glib::Priority,
786 cancellable: Option<&impl IsA<Cancellable>>,
787 callback: P,
788 ) {
789 let main_context = glib::MainContext::ref_thread_default();
790 let is_main_context_owner = main_context.is_owner();
791 let has_acquired_main_context = (!is_main_context_owner)
792 .then(|| main_context.acquire().ok())
793 .flatten();
794 assert!(
795 is_main_context_owner || has_acquired_main_context.is_some(),
796 "Async operations only allowed if the thread is owning the MainContext"
797 );
798
799 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
800 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
801 unsafe extern "C" fn create_readwrite_async_trampoline<
802 P: FnOnce(Result<FileIOStream, glib::Error>) + 'static,
803 >(
804 _source_object: *mut glib::gobject_ffi::GObject,
805 res: *mut crate::ffi::GAsyncResult,
806 user_data: glib::ffi::gpointer,
807 ) {
808 unsafe {
809 let mut error = std::ptr::null_mut();
810 let ret =
811 ffi::g_file_create_readwrite_finish(_source_object as *mut _, res, &mut error);
812 let result = if error.is_null() {
813 Ok(from_glib_full(ret))
814 } else {
815 Err(from_glib_full(error))
816 };
817 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
818 Box_::from_raw(user_data as *mut _);
819 let callback: P = callback.into_inner();
820 callback(result);
821 }
822 }
823 let callback = create_readwrite_async_trampoline::<P>;
824 unsafe {
825 ffi::g_file_create_readwrite_async(
826 self.as_ref().to_glib_none().0,
827 flags.into_glib(),
828 io_priority.into_glib(),
829 cancellable.map(|p| p.as_ref()).to_glib_none().0,
830 Some(callback),
831 Box_::into_raw(user_data) as *mut _,
832 );
833 }
834 }
835
836 fn create_readwrite_future(
837 &self,
838 flags: FileCreateFlags,
839 io_priority: glib::Priority,
840 ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileIOStream, glib::Error>> + 'static>>
841 {
842 Box_::pin(crate::GioFuture::new(
843 self,
844 move |obj, cancellable, send| {
845 obj.create_readwrite_async(flags, io_priority, Some(cancellable), move |res| {
846 send.resolve(res);
847 });
848 },
849 ))
850 }
851
852 /// message);
853 /// }
854 /// ]|
855 ///
856 /// If @cancellable is not [`None`], then the operation can be cancelled by
857 /// triggering the cancellable object from another thread. If the operation
858 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
859 /// ## `cancellable`
860 /// optional #GCancellable object,
861 /// [`None`] to ignore
862 ///
863 /// # Returns
864 ///
865 /// [`true`] if the file was deleted. [`false`] otherwise.
866 #[doc(alias = "g_file_delete")]
867 fn delete(&self, cancellable: Option<&impl IsA<Cancellable>>) -> Result<(), glib::Error> {
868 unsafe {
869 let mut error = std::ptr::null_mut();
870 let is_ok = ffi::g_file_delete(
871 self.as_ref().to_glib_none().0,
872 cancellable.map(|p| p.as_ref()).to_glib_none().0,
873 &mut error,
874 );
875 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
876 if error.is_null() {
877 Ok(())
878 } else {
879 Err(from_glib_full(error))
880 }
881 }
882 }
883
884 /// Asynchronously delete a file. If the @self is a directory, it will
885 /// only be deleted if it is empty. This has the same semantics as
886 /// g_unlink().
887 /// ## `io_priority`
888 /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
889 /// ## `cancellable`
890 /// optional #GCancellable object,
891 /// [`None`] to ignore
892 /// ## `callback`
893 /// a #GAsyncReadyCallback to call
894 /// when the request is satisfied
895 #[doc(alias = "g_file_delete_async")]
896 fn delete_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
897 &self,
898 io_priority: glib::Priority,
899 cancellable: Option<&impl IsA<Cancellable>>,
900 callback: P,
901 ) {
902 let main_context = glib::MainContext::ref_thread_default();
903 let is_main_context_owner = main_context.is_owner();
904 let has_acquired_main_context = (!is_main_context_owner)
905 .then(|| main_context.acquire().ok())
906 .flatten();
907 assert!(
908 is_main_context_owner || has_acquired_main_context.is_some(),
909 "Async operations only allowed if the thread is owning the MainContext"
910 );
911
912 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
913 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
914 unsafe extern "C" fn delete_async_trampoline<
915 P: FnOnce(Result<(), glib::Error>) + 'static,
916 >(
917 _source_object: *mut glib::gobject_ffi::GObject,
918 res: *mut crate::ffi::GAsyncResult,
919 user_data: glib::ffi::gpointer,
920 ) {
921 unsafe {
922 let mut error = std::ptr::null_mut();
923 ffi::g_file_delete_finish(_source_object as *mut _, res, &mut error);
924 let result = if error.is_null() {
925 Ok(())
926 } else {
927 Err(from_glib_full(error))
928 };
929 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
930 Box_::from_raw(user_data as *mut _);
931 let callback: P = callback.into_inner();
932 callback(result);
933 }
934 }
935 let callback = delete_async_trampoline::<P>;
936 unsafe {
937 ffi::g_file_delete_async(
938 self.as_ref().to_glib_none().0,
939 io_priority.into_glib(),
940 cancellable.map(|p| p.as_ref()).to_glib_none().0,
941 Some(callback),
942 Box_::into_raw(user_data) as *mut _,
943 );
944 }
945 }
946
947 fn delete_future(
948 &self,
949 io_priority: glib::Priority,
950 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
951 Box_::pin(crate::GioFuture::new(
952 self,
953 move |obj, cancellable, send| {
954 obj.delete_async(io_priority, Some(cancellable), move |res| {
955 send.resolve(res);
956 });
957 },
958 ))
959 }
960
961 /// Duplicates a #GFile handle. This operation does not duplicate
962 /// the actual file or directory represented by the #GFile; see
963 /// g_file_copy() if attempting to copy a file.
964 ///
965 /// g_file_dup() is useful when a second handle is needed to the same underlying
966 /// file, for use in a separate thread (#GFile is not thread-safe). For use
967 /// within the same thread, use g_object_ref() to increment the existing object’s
968 /// reference count.
969 ///
970 /// This call does no blocking I/O.
971 ///
972 /// # Returns
973 ///
974 /// a new #GFile that is a duplicate
975 /// of the given #GFile.
976 #[doc(alias = "g_file_dup")]
977 #[must_use]
978 fn dup(&self) -> File {
979 unsafe { from_glib_full(ffi::g_file_dup(self.as_ref().to_glib_none().0)) }
980 }
981
982 /// Starts an asynchronous eject on a mountable.
983 /// When this operation has completed, @callback will be called with
984 /// @user_user data, and the operation can be finalized with
985 /// g_file_eject_mountable_with_operation_finish().
986 ///
987 /// If @cancellable is not [`None`], then the operation can be cancelled by
988 /// triggering the cancellable object from another thread. If the operation
989 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
990 /// ## `flags`
991 /// flags affecting the operation
992 /// ## `mount_operation`
993 /// a #GMountOperation,
994 /// or [`None`] to avoid user interaction
995 /// ## `cancellable`
996 /// optional #GCancellable object,
997 /// [`None`] to ignore
998 /// ## `callback`
999 /// a #GAsyncReadyCallback
1000 /// to call when the request is satisfied
1001 #[doc(alias = "g_file_eject_mountable_with_operation")]
1002 fn eject_mountable_with_operation<P: FnOnce(Result<(), glib::Error>) + 'static>(
1003 &self,
1004 flags: MountUnmountFlags,
1005 mount_operation: Option<&impl IsA<MountOperation>>,
1006 cancellable: Option<&impl IsA<Cancellable>>,
1007 callback: P,
1008 ) {
1009 let main_context = glib::MainContext::ref_thread_default();
1010 let is_main_context_owner = main_context.is_owner();
1011 let has_acquired_main_context = (!is_main_context_owner)
1012 .then(|| main_context.acquire().ok())
1013 .flatten();
1014 assert!(
1015 is_main_context_owner || has_acquired_main_context.is_some(),
1016 "Async operations only allowed if the thread is owning the MainContext"
1017 );
1018
1019 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
1020 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
1021 unsafe extern "C" fn eject_mountable_with_operation_trampoline<
1022 P: FnOnce(Result<(), glib::Error>) + 'static,
1023 >(
1024 _source_object: *mut glib::gobject_ffi::GObject,
1025 res: *mut crate::ffi::GAsyncResult,
1026 user_data: glib::ffi::gpointer,
1027 ) {
1028 unsafe {
1029 let mut error = std::ptr::null_mut();
1030 ffi::g_file_eject_mountable_with_operation_finish(
1031 _source_object as *mut _,
1032 res,
1033 &mut error,
1034 );
1035 let result = if error.is_null() {
1036 Ok(())
1037 } else {
1038 Err(from_glib_full(error))
1039 };
1040 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
1041 Box_::from_raw(user_data as *mut _);
1042 let callback: P = callback.into_inner();
1043 callback(result);
1044 }
1045 }
1046 let callback = eject_mountable_with_operation_trampoline::<P>;
1047 unsafe {
1048 ffi::g_file_eject_mountable_with_operation(
1049 self.as_ref().to_glib_none().0,
1050 flags.into_glib(),
1051 mount_operation.map(|p| p.as_ref()).to_glib_none().0,
1052 cancellable.map(|p| p.as_ref()).to_glib_none().0,
1053 Some(callback),
1054 Box_::into_raw(user_data) as *mut _,
1055 );
1056 }
1057 }
1058
1059 fn eject_mountable_with_operation_future(
1060 &self,
1061 flags: MountUnmountFlags,
1062 mount_operation: Option<&(impl IsA<MountOperation> + Clone + 'static)>,
1063 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
1064 let mount_operation = mount_operation.map(ToOwned::to_owned);
1065 Box_::pin(crate::GioFuture::new(
1066 self,
1067 move |obj, cancellable, send| {
1068 obj.eject_mountable_with_operation(
1069 flags,
1070 mount_operation.as_ref().map(::std::borrow::Borrow::borrow),
1071 Some(cancellable),
1072 move |res| {
1073 send.resolve(res);
1074 },
1075 );
1076 },
1077 ))
1078 }
1079
1080 /// Gets the requested information about the files in a directory.
1081 /// The result is a [`FileEnumerator`][crate::FileEnumerator] object that will give out
1082 /// [`FileInfo`][crate::FileInfo] objects for all the files in the directory.
1083 ///
1084 /// The @attributes value is a string that specifies the file
1085 /// attributes that should be gathered. It is not an error if
1086 /// it's not possible to read a particular requested attribute
1087 /// from a file - it just won't be set. @attributes should
1088 /// be a comma-separated list of attributes or attribute wildcards.
1089 /// The wildcard `*` means all attributes, and a wildcard like
1090 /// `"standard::*"` means all attributes in the standard namespace.
1091 /// An example attribute query be `"standard::*,owner::user"`.
1092 /// The standard attributes are available as defines, like
1093 /// `FILE_ATTRIBUTE_STANDARD_NAME`. `FILE_ATTRIBUTE_STANDARD_NAME` should
1094 /// always be specified if you plan to call [`FileEnumeratorExt::child()`][crate::prelude::FileEnumeratorExt::child()] or
1095 /// `FileEnumerator::iterate()` on the returned enumerator.
1096 ///
1097 /// If @cancellable is not `NULL`, then the operation can be cancelled
1098 /// by triggering the cancellable object from another thread. If the
1099 /// operation was cancelled, the error [error@Gio.IOErrorEnum.CANCELLED] will be
1100 /// returned.
1101 ///
1102 /// If the file does not exist, the [error@Gio.IOErrorEnum.NOT_FOUND] error will
1103 /// be returned. If the file is not a directory, the [error@Gio.IOErrorEnum.NOT_DIRECTORY]
1104 /// error will be returned. Other errors are possible too.
1105 /// ## `attributes`
1106 /// an attribute query string
1107 /// ## `flags`
1108 /// a set of #GFileQueryInfoFlags
1109 /// ## `cancellable`
1110 /// optional #GCancellable object,
1111 /// [`None`] to ignore
1112 ///
1113 /// # Returns
1114 ///
1115 /// A #GFileEnumerator if successful,
1116 /// [`None`] on error. Free the returned object with `GObject::Object::unref()`.
1117 #[doc(alias = "g_file_enumerate_children")]
1118 fn enumerate_children(
1119 &self,
1120 attributes: &str,
1121 flags: FileQueryInfoFlags,
1122 cancellable: Option<&impl IsA<Cancellable>>,
1123 ) -> Result<FileEnumerator, glib::Error> {
1124 unsafe {
1125 let mut error = std::ptr::null_mut();
1126 let ret = ffi::g_file_enumerate_children(
1127 self.as_ref().to_glib_none().0,
1128 attributes.to_glib_none().0,
1129 flags.into_glib(),
1130 cancellable.map(|p| p.as_ref()).to_glib_none().0,
1131 &mut error,
1132 );
1133 if error.is_null() {
1134 Ok(from_glib_full(ret))
1135 } else {
1136 Err(from_glib_full(error))
1137 }
1138 }
1139 }
1140
1141 #[doc(alias = "g_file_equal")]
1142 fn equal(&self, file2: &impl IsA<File>) -> bool {
1143 unsafe {
1144 from_glib(ffi::g_file_equal(
1145 self.as_ref().to_glib_none().0,
1146 file2.as_ref().to_glib_none().0,
1147 ))
1148 }
1149 }
1150
1151 /// Gets a #GMount for the #GFile.
1152 ///
1153 /// #GMount is returned only for user interesting locations, see
1154 /// #GVolumeMonitor. If the #GFileIface for @self does not have a #mount,
1155 /// @error will be set to [`IOErrorEnum::NotFound`][crate::IOErrorEnum::NotFound] and [`None`] #will be returned.
1156 ///
1157 /// If @cancellable is not [`None`], then the operation can be cancelled by
1158 /// triggering the cancellable object from another thread. If the operation
1159 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
1160 /// ## `cancellable`
1161 /// optional #GCancellable object,
1162 /// [`None`] to ignore
1163 ///
1164 /// # Returns
1165 ///
1166 /// a #GMount where the @self is located
1167 /// or [`None`] on error.
1168 /// Free the returned object with g_object_unref().
1169 #[doc(alias = "g_file_find_enclosing_mount")]
1170 fn find_enclosing_mount(
1171 &self,
1172 cancellable: Option<&impl IsA<Cancellable>>,
1173 ) -> Result<Mount, glib::Error> {
1174 unsafe {
1175 let mut error = std::ptr::null_mut();
1176 let ret = ffi::g_file_find_enclosing_mount(
1177 self.as_ref().to_glib_none().0,
1178 cancellable.map(|p| p.as_ref()).to_glib_none().0,
1179 &mut error,
1180 );
1181 if error.is_null() {
1182 Ok(from_glib_full(ret))
1183 } else {
1184 Err(from_glib_full(error))
1185 }
1186 }
1187 }
1188
1189 /// Gets the base name (the last component of the path) for a given #GFile.
1190 ///
1191 /// If called for the top level of a system (such as the filesystem root
1192 /// or a uri like sftp://host/) it will return a single directory separator
1193 /// (and on Windows, possibly a drive letter).
1194 ///
1195 /// The base name is a byte string (not UTF-8). It has no defined encoding
1196 /// or rules other than it may not contain zero bytes. If you want to use
1197 /// filenames in a user interface you should use the display name that you
1198 /// can get by requesting the [`FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME`][crate::FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME]
1199 /// attribute with g_file_query_info().
1200 ///
1201 /// This call does no blocking I/O.
1202 ///
1203 /// # Returns
1204 ///
1205 /// string containing the #GFile's
1206 /// base name, or [`None`] if given #GFile is invalid. The returned string
1207 /// should be freed with g_free() when no longer needed.
1208 #[doc(alias = "g_file_get_basename")]
1209 #[doc(alias = "get_basename")]
1210 fn basename(&self) -> Option<std::path::PathBuf> {
1211 unsafe { from_glib_full(ffi::g_file_get_basename(self.as_ref().to_glib_none().0)) }
1212 }
1213
1214 /// Gets a child of @self with basename equal to @name.
1215 ///
1216 /// Note that the file with that specific name might not exist, but
1217 /// you can still have a #GFile that points to it. You can use this
1218 /// for instance to create that file.
1219 ///
1220 /// This call does no blocking I/O.
1221 /// ## `name`
1222 /// string containing the child's basename
1223 ///
1224 /// # Returns
1225 ///
1226 /// a #GFile to a child specified by @name.
1227 /// Free the returned object with g_object_unref().
1228 #[doc(alias = "g_file_get_child")]
1229 #[doc(alias = "get_child")]
1230 #[must_use]
1231 fn child(&self, name: impl AsRef<std::path::Path>) -> File {
1232 unsafe {
1233 from_glib_full(ffi::g_file_get_child(
1234 self.as_ref().to_glib_none().0,
1235 name.as_ref().to_glib_none().0,
1236 ))
1237 }
1238 }
1239
1240 /// Gets the child of @self for a given @display_name (i.e. a UTF-8
1241 /// version of the name). If this function fails, it returns [`None`]
1242 /// and @error will be set. This is very useful when constructing a
1243 /// #GFile for a new file and the user entered the filename in the
1244 /// user interface, for instance when you select a directory and
1245 /// type a filename in the file selector.
1246 ///
1247 /// This call does no blocking I/O.
1248 /// ## `display_name`
1249 /// string to a possible child
1250 ///
1251 /// # Returns
1252 ///
1253 /// a #GFile to the specified child, or
1254 /// [`None`] if the display name couldn't be converted.
1255 /// Free the returned object with g_object_unref().
1256 #[doc(alias = "g_file_get_child_for_display_name")]
1257 #[doc(alias = "get_child_for_display_name")]
1258 fn child_for_display_name(&self, display_name: &str) -> Result<File, glib::Error> {
1259 unsafe {
1260 let mut error = std::ptr::null_mut();
1261 let ret = ffi::g_file_get_child_for_display_name(
1262 self.as_ref().to_glib_none().0,
1263 display_name.to_glib_none().0,
1264 &mut error,
1265 );
1266 if error.is_null() {
1267 Ok(from_glib_full(ret))
1268 } else {
1269 Err(from_glib_full(error))
1270 }
1271 }
1272 }
1273
1274 /// Gets the parent directory for the @self.
1275 /// If the @self represents the root directory of the
1276 /// file system, then [`None`] will be returned.
1277 ///
1278 /// This call does no blocking I/O.
1279 ///
1280 /// # Returns
1281 ///
1282 /// a #GFile structure to the
1283 /// parent of the given #GFile or [`None`] if there is no parent. Free
1284 /// the returned object with g_object_unref().
1285 #[doc(alias = "g_file_get_parent")]
1286 #[doc(alias = "get_parent")]
1287 #[must_use]
1288 fn parent(&self) -> Option<File> {
1289 unsafe { from_glib_full(ffi::g_file_get_parent(self.as_ref().to_glib_none().0)) }
1290 }
1291
1292 /// Gets the parse name of the @self.
1293 /// A parse name is a UTF-8 string that describes the
1294 /// file such that one can get the #GFile back using
1295 /// g_file_parse_name().
1296 ///
1297 /// This is generally used to show the #GFile as a nice
1298 /// full-pathname kind of string in a user interface,
1299 /// like in a location entry.
1300 ///
1301 /// For local files with names that can safely be converted
1302 /// to UTF-8 the pathname is used, otherwise the IRI is used
1303 /// (a form of URI that allows UTF-8 characters unescaped).
1304 ///
1305 /// This call does no blocking I/O.
1306 ///
1307 /// # Returns
1308 ///
1309 /// a string containing the #GFile's parse name.
1310 /// The returned string should be freed with g_free()
1311 /// when no longer needed.
1312 #[doc(alias = "g_file_get_parse_name")]
1313 #[doc(alias = "get_parse_name")]
1314 fn parse_name(&self) -> glib::GString {
1315 unsafe { from_glib_full(ffi::g_file_get_parse_name(self.as_ref().to_glib_none().0)) }
1316 }
1317
1318 /// Gets the local pathname for #GFile, if one exists. If non-[`None`], this is
1319 /// guaranteed to be an absolute, canonical path. It might contain symlinks.
1320 ///
1321 /// This call does no blocking I/O.
1322 ///
1323 /// # Returns
1324 ///
1325 /// string containing the #GFile's path,
1326 /// or [`None`] if no such path exists. The returned string should be freed
1327 /// with g_free() when no longer needed.
1328 #[doc(alias = "g_file_get_path")]
1329 #[doc(alias = "get_path")]
1330 fn path(&self) -> Option<std::path::PathBuf> {
1331 unsafe { from_glib_full(ffi::g_file_get_path(self.as_ref().to_glib_none().0)) }
1332 }
1333
1334 /// Gets the path for @descendant relative to @self.
1335 ///
1336 /// This call does no blocking I/O.
1337 /// ## `descendant`
1338 /// input #GFile
1339 ///
1340 /// # Returns
1341 ///
1342 /// string with the relative path from
1343 /// @descendant to @self, or [`None`] if @descendant doesn't have @self as
1344 /// prefix. The returned string should be freed with g_free() when
1345 /// no longer needed.
1346 #[doc(alias = "g_file_get_relative_path")]
1347 #[doc(alias = "get_relative_path")]
1348 fn relative_path(&self, descendant: &impl IsA<File>) -> Option<std::path::PathBuf> {
1349 unsafe {
1350 from_glib_full(ffi::g_file_get_relative_path(
1351 self.as_ref().to_glib_none().0,
1352 descendant.as_ref().to_glib_none().0,
1353 ))
1354 }
1355 }
1356
1357 /// Gets the URI for the @self.
1358 ///
1359 /// This call does no blocking I/O.
1360 ///
1361 /// # Returns
1362 ///
1363 /// a string containing the #GFile's URI. If the #GFile was constructed
1364 /// with an invalid URI, an invalid URI is returned.
1365 /// The returned string should be freed with g_free()
1366 /// when no longer needed.
1367 #[doc(alias = "g_file_get_uri")]
1368 #[doc(alias = "get_uri")]
1369 fn uri(&self) -> glib::GString {
1370 unsafe { from_glib_full(ffi::g_file_get_uri(self.as_ref().to_glib_none().0)) }
1371 }
1372
1373 /// Gets the URI scheme for a #GFile.
1374 /// RFC 3986 decodes the scheme as:
1375 ///
1376 /// ```text
1377 /// URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
1378 /// ```
1379 /// Common schemes include "file", "http", "ftp", etc.
1380 ///
1381 /// The scheme can be different from the one used to construct the #GFile,
1382 /// in that it might be replaced with one that is logically equivalent to the #GFile.
1383 ///
1384 /// This call does no blocking I/O.
1385 ///
1386 /// # Returns
1387 ///
1388 /// a string containing the URI scheme for the given
1389 /// #GFile or [`None`] if the #GFile was constructed with an invalid URI. The
1390 /// returned string should be freed with g_free() when no longer needed.
1391 #[doc(alias = "g_file_get_uri_scheme")]
1392 #[doc(alias = "get_uri_scheme")]
1393 fn uri_scheme(&self) -> Option<glib::GString> {
1394 unsafe { from_glib_full(ffi::g_file_get_uri_scheme(self.as_ref().to_glib_none().0)) }
1395 }
1396
1397 /// Checks if @self has a parent, and optionally, if it is @parent.
1398 ///
1399 /// If @parent is [`None`] then this function returns [`true`] if @self has any
1400 /// parent at all. If @parent is non-[`None`] then [`true`] is only returned
1401 /// if @self is an immediate child of @parent.
1402 /// ## `parent`
1403 /// the parent to check for, or [`None`]
1404 ///
1405 /// # Returns
1406 ///
1407 /// [`true`] if @self is an immediate child of @parent (or any parent in
1408 /// the case that @parent is [`None`]).
1409 #[doc(alias = "g_file_has_parent")]
1410 fn has_parent(&self, parent: Option<&impl IsA<File>>) -> bool {
1411 unsafe {
1412 from_glib(ffi::g_file_has_parent(
1413 self.as_ref().to_glib_none().0,
1414 parent.map(|p| p.as_ref()).to_glib_none().0,
1415 ))
1416 }
1417 }
1418
1419 /// Checks whether @self has the prefix specified by @prefix.
1420 ///
1421 /// In other words, if the names of initial elements of @self's
1422 /// pathname match @prefix. Only full pathname elements are matched,
1423 /// so a path like /foo is not considered a prefix of /foobar, only
1424 /// of /foo/bar.
1425 ///
1426 /// A #GFile is not a prefix of itself. If you want to check for
1427 /// equality, use g_file_equal().
1428 ///
1429 /// This call does no I/O, as it works purely on names. As such it can
1430 /// sometimes return [`false`] even if @self is inside a @prefix (from a
1431 /// filesystem point of view), because the prefix of @self is an alias
1432 /// of @prefix.
1433 /// ## `prefix`
1434 /// input #GFile
1435 ///
1436 /// # Returns
1437 ///
1438 /// [`true`] if the @self's parent, grandparent, etc is @prefix,
1439 /// [`false`] otherwise.
1440 #[doc(alias = "g_file_has_prefix")]
1441 fn has_prefix(&self, prefix: &impl IsA<File>) -> bool {
1442 unsafe {
1443 from_glib(ffi::g_file_has_prefix(
1444 self.as_ref().to_glib_none().0,
1445 prefix.as_ref().to_glib_none().0,
1446 ))
1447 }
1448 }
1449
1450 /// Checks to see if a #GFile has a given URI scheme.
1451 ///
1452 /// This call does no blocking I/O.
1453 /// ## `uri_scheme`
1454 /// a string containing a URI scheme
1455 ///
1456 /// # Returns
1457 ///
1458 /// [`true`] if #GFile's backend supports the
1459 /// given URI scheme, [`false`] if URI scheme is [`None`],
1460 /// not supported, or #GFile is invalid.
1461 #[doc(alias = "g_file_has_uri_scheme")]
1462 fn has_uri_scheme(&self, uri_scheme: &str) -> bool {
1463 unsafe {
1464 from_glib(ffi::g_file_has_uri_scheme(
1465 self.as_ref().to_glib_none().0,
1466 uri_scheme.to_glib_none().0,
1467 ))
1468 }
1469 }
1470
1471 /// Checks to see if a file is native to the platform.
1472 ///
1473 /// A native file is one expressed in the platform-native filename format,
1474 /// e.g. "C:\Windows" or "/usr/bin/". This does not mean the file is local,
1475 /// as it might be on a locally mounted remote filesystem.
1476 ///
1477 /// On some systems non-native files may be available using the native
1478 /// filesystem via a userspace filesystem (FUSE), in these cases this call
1479 /// will return [`false`], but g_file_get_path() will still return a native path.
1480 ///
1481 /// This call does no blocking I/O.
1482 ///
1483 /// # Returns
1484 ///
1485 /// [`true`] if @self is native
1486 #[doc(alias = "g_file_is_native")]
1487 fn is_native(&self) -> bool {
1488 unsafe { from_glib(ffi::g_file_is_native(self.as_ref().to_glib_none().0)) }
1489 }
1490
1491 /// Loads the contents of @self and returns it as #GBytes.
1492 ///
1493 /// If @self is a resource:// based URI, the resulting bytes will reference the
1494 /// embedded resource instead of a copy. Otherwise, this is equivalent to calling
1495 /// g_file_load_contents() and g_bytes_new_take().
1496 ///
1497 /// For resources, @etag_out will be set to [`None`].
1498 ///
1499 /// The data contained in the resulting #GBytes is always zero-terminated, but
1500 /// this is not included in the #GBytes length. The resulting #GBytes should be
1501 /// freed with g_bytes_unref() when no longer in use.
1502 /// ## `cancellable`
1503 /// a #GCancellable or [`None`]
1504 ///
1505 /// # Returns
1506 ///
1507 /// a #GBytes or [`None`] and @error is set
1508 ///
1509 /// ## `etag_out`
1510 /// a location to place the current
1511 /// entity tag for the file, or [`None`] if the entity tag is not needed
1512 #[doc(alias = "g_file_load_bytes")]
1513 fn load_bytes(
1514 &self,
1515 cancellable: Option<&impl IsA<Cancellable>>,
1516 ) -> Result<(glib::Bytes, Option<glib::GString>), glib::Error> {
1517 unsafe {
1518 let mut etag_out = std::ptr::null_mut();
1519 let mut error = std::ptr::null_mut();
1520 let ret = ffi::g_file_load_bytes(
1521 self.as_ref().to_glib_none().0,
1522 cancellable.map(|p| p.as_ref()).to_glib_none().0,
1523 &mut etag_out,
1524 &mut error,
1525 );
1526 if error.is_null() {
1527 Ok((from_glib_full(ret), from_glib_full(etag_out)))
1528 } else {
1529 Err(from_glib_full(error))
1530 }
1531 }
1532 }
1533
1534 /// Asynchronously loads the contents of @self as #GBytes.
1535 ///
1536 /// If @self is a resource:// based URI, the resulting bytes will reference the
1537 /// embedded resource instead of a copy. Otherwise, this is equivalent to calling
1538 /// g_file_load_contents_async() and g_bytes_new_take().
1539 ///
1540 /// @callback should call g_file_load_bytes_finish() to get the result of this
1541 /// asynchronous operation.
1542 ///
1543 /// See g_file_load_bytes() for more information.
1544 /// ## `cancellable`
1545 /// a #GCancellable or [`None`]
1546 /// ## `callback`
1547 /// a #GAsyncReadyCallback
1548 /// to call when the request is satisfied
1549 #[doc(alias = "g_file_load_bytes_async")]
1550 fn load_bytes_async<
1551 P: FnOnce(Result<(glib::Bytes, Option<glib::GString>), glib::Error>) + 'static,
1552 >(
1553 &self,
1554 cancellable: Option<&impl IsA<Cancellable>>,
1555 callback: P,
1556 ) {
1557 let main_context = glib::MainContext::ref_thread_default();
1558 let is_main_context_owner = main_context.is_owner();
1559 let has_acquired_main_context = (!is_main_context_owner)
1560 .then(|| main_context.acquire().ok())
1561 .flatten();
1562 assert!(
1563 is_main_context_owner || has_acquired_main_context.is_some(),
1564 "Async operations only allowed if the thread is owning the MainContext"
1565 );
1566
1567 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
1568 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
1569 unsafe extern "C" fn load_bytes_async_trampoline<
1570 P: FnOnce(Result<(glib::Bytes, Option<glib::GString>), glib::Error>) + 'static,
1571 >(
1572 _source_object: *mut glib::gobject_ffi::GObject,
1573 res: *mut crate::ffi::GAsyncResult,
1574 user_data: glib::ffi::gpointer,
1575 ) {
1576 unsafe {
1577 let mut error = std::ptr::null_mut();
1578 let mut etag_out = std::ptr::null_mut();
1579 let ret = ffi::g_file_load_bytes_finish(
1580 _source_object as *mut _,
1581 res,
1582 &mut etag_out,
1583 &mut error,
1584 );
1585 let result = if error.is_null() {
1586 Ok((from_glib_full(ret), from_glib_full(etag_out)))
1587 } else {
1588 Err(from_glib_full(error))
1589 };
1590 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
1591 Box_::from_raw(user_data as *mut _);
1592 let callback: P = callback.into_inner();
1593 callback(result);
1594 }
1595 }
1596 let callback = load_bytes_async_trampoline::<P>;
1597 unsafe {
1598 ffi::g_file_load_bytes_async(
1599 self.as_ref().to_glib_none().0,
1600 cancellable.map(|p| p.as_ref()).to_glib_none().0,
1601 Some(callback),
1602 Box_::into_raw(user_data) as *mut _,
1603 );
1604 }
1605 }
1606
1607 fn load_bytes_future(
1608 &self,
1609 ) -> Pin<
1610 Box_<
1611 dyn std::future::Future<
1612 Output = Result<(glib::Bytes, Option<glib::GString>), glib::Error>,
1613 > + 'static,
1614 >,
1615 > {
1616 Box_::pin(crate::GioFuture::new(
1617 self,
1618 move |obj, cancellable, send| {
1619 obj.load_bytes_async(Some(cancellable), move |res| {
1620 send.resolve(res);
1621 });
1622 },
1623 ))
1624 }
1625
1626 /// Creates a directory.
1627 ///
1628 /// Note that this will only create a child directory
1629 /// of the immediate parent directory of the path or URI given by the #GFile.
1630 /// To recursively create directories, see g_file_make_directory_with_parents().
1631 ///
1632 /// This function will fail if the parent directory does not exist, setting
1633 /// @error to [`IOErrorEnum::NotFound`][crate::IOErrorEnum::NotFound]. If the file system doesn't support
1634 /// creating directories, this function will fail, setting @error to
1635 /// [`IOErrorEnum::NotSupported`][crate::IOErrorEnum::NotSupported]. If the directory already exists,
1636 /// [error@Gio.IOErrorEnum.EXISTS] will be returned.
1637 ///
1638 /// For a local #GFile the newly created directory will have the default
1639 /// (current) ownership and permissions of the current process.
1640 ///
1641 /// If @cancellable is not [`None`], then the operation can be cancelled by
1642 /// triggering the cancellable object from another thread. If the operation
1643 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
1644 /// ## `cancellable`
1645 /// optional #GCancellable object,
1646 /// [`None`] to ignore
1647 ///
1648 /// # Returns
1649 ///
1650 /// [`true`] on successful creation, [`false`] otherwise.
1651 #[doc(alias = "g_file_make_directory")]
1652 fn make_directory(
1653 &self,
1654 cancellable: Option<&impl IsA<Cancellable>>,
1655 ) -> Result<(), glib::Error> {
1656 unsafe {
1657 let mut error = std::ptr::null_mut();
1658 let is_ok = ffi::g_file_make_directory(
1659 self.as_ref().to_glib_none().0,
1660 cancellable.map(|p| p.as_ref()).to_glib_none().0,
1661 &mut error,
1662 );
1663 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
1664 if error.is_null() {
1665 Ok(())
1666 } else {
1667 Err(from_glib_full(error))
1668 }
1669 }
1670 }
1671
1672 /// Asynchronously creates a directory.
1673 /// ## `io_priority`
1674 /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
1675 /// ## `cancellable`
1676 /// optional #GCancellable object,
1677 /// [`None`] to ignore
1678 /// ## `callback`
1679 /// a #GAsyncReadyCallback to call
1680 /// when the request is satisfied
1681 #[doc(alias = "g_file_make_directory_async")]
1682 fn make_directory_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
1683 &self,
1684 io_priority: glib::Priority,
1685 cancellable: Option<&impl IsA<Cancellable>>,
1686 callback: P,
1687 ) {
1688 let main_context = glib::MainContext::ref_thread_default();
1689 let is_main_context_owner = main_context.is_owner();
1690 let has_acquired_main_context = (!is_main_context_owner)
1691 .then(|| main_context.acquire().ok())
1692 .flatten();
1693 assert!(
1694 is_main_context_owner || has_acquired_main_context.is_some(),
1695 "Async operations only allowed if the thread is owning the MainContext"
1696 );
1697
1698 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
1699 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
1700 unsafe extern "C" fn make_directory_async_trampoline<
1701 P: FnOnce(Result<(), glib::Error>) + 'static,
1702 >(
1703 _source_object: *mut glib::gobject_ffi::GObject,
1704 res: *mut crate::ffi::GAsyncResult,
1705 user_data: glib::ffi::gpointer,
1706 ) {
1707 unsafe {
1708 let mut error = std::ptr::null_mut();
1709 ffi::g_file_make_directory_finish(_source_object as *mut _, res, &mut error);
1710 let result = if error.is_null() {
1711 Ok(())
1712 } else {
1713 Err(from_glib_full(error))
1714 };
1715 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
1716 Box_::from_raw(user_data as *mut _);
1717 let callback: P = callback.into_inner();
1718 callback(result);
1719 }
1720 }
1721 let callback = make_directory_async_trampoline::<P>;
1722 unsafe {
1723 ffi::g_file_make_directory_async(
1724 self.as_ref().to_glib_none().0,
1725 io_priority.into_glib(),
1726 cancellable.map(|p| p.as_ref()).to_glib_none().0,
1727 Some(callback),
1728 Box_::into_raw(user_data) as *mut _,
1729 );
1730 }
1731 }
1732
1733 fn make_directory_future(
1734 &self,
1735 io_priority: glib::Priority,
1736 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
1737 Box_::pin(crate::GioFuture::new(
1738 self,
1739 move |obj, cancellable, send| {
1740 obj.make_directory_async(io_priority, Some(cancellable), move |res| {
1741 send.resolve(res);
1742 });
1743 },
1744 ))
1745 }
1746
1747 /// Creates a directory and any parent directories that may not
1748 /// exist similar to 'mkdir -p'. If the file system does not support
1749 /// creating directories, this function will fail, setting @error to
1750 /// [`IOErrorEnum::NotSupported`][crate::IOErrorEnum::NotSupported]. If the directory itself already exists,
1751 /// this function will fail setting @error to [`IOErrorEnum::Exists`][crate::IOErrorEnum::Exists], unlike
1752 /// the similar g_mkdir_with_parents().
1753 ///
1754 /// For a local #GFile the newly created directories will have the default
1755 /// (current) ownership and permissions of the current process.
1756 ///
1757 /// If @cancellable is not [`None`], then the operation can be cancelled by
1758 /// triggering the cancellable object from another thread. If the operation
1759 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
1760 /// ## `cancellable`
1761 /// optional #GCancellable object,
1762 /// [`None`] to ignore
1763 ///
1764 /// # Returns
1765 ///
1766 /// [`true`] if all directories have been successfully created, [`false`]
1767 /// otherwise.
1768 #[doc(alias = "g_file_make_directory_with_parents")]
1769 fn make_directory_with_parents(
1770 &self,
1771 cancellable: Option<&impl IsA<Cancellable>>,
1772 ) -> Result<(), glib::Error> {
1773 unsafe {
1774 let mut error = std::ptr::null_mut();
1775 let is_ok = ffi::g_file_make_directory_with_parents(
1776 self.as_ref().to_glib_none().0,
1777 cancellable.map(|p| p.as_ref()).to_glib_none().0,
1778 &mut error,
1779 );
1780 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
1781 if error.is_null() {
1782 Ok(())
1783 } else {
1784 Err(from_glib_full(error))
1785 }
1786 }
1787 }
1788
1789 /// Creates a symbolic link named @self which contains the string
1790 /// @symlink_value.
1791 ///
1792 /// If @cancellable is not [`None`], then the operation can be cancelled by
1793 /// triggering the cancellable object from another thread. If the operation
1794 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
1795 /// ## `symlink_value`
1796 /// a string with the path for the target
1797 /// of the new symlink
1798 /// ## `cancellable`
1799 /// optional #GCancellable object,
1800 /// [`None`] to ignore
1801 ///
1802 /// # Returns
1803 ///
1804 /// [`true`] on the creation of a new symlink, [`false`] otherwise.
1805 #[doc(alias = "g_file_make_symbolic_link")]
1806 fn make_symbolic_link(
1807 &self,
1808 symlink_value: impl AsRef<std::path::Path>,
1809 cancellable: Option<&impl IsA<Cancellable>>,
1810 ) -> Result<(), glib::Error> {
1811 unsafe {
1812 let mut error = std::ptr::null_mut();
1813 let is_ok = ffi::g_file_make_symbolic_link(
1814 self.as_ref().to_glib_none().0,
1815 symlink_value.as_ref().to_glib_none().0,
1816 cancellable.map(|p| p.as_ref()).to_glib_none().0,
1817 &mut error,
1818 );
1819 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
1820 if error.is_null() {
1821 Ok(())
1822 } else {
1823 Err(from_glib_full(error))
1824 }
1825 }
1826 }
1827
1828 /// Recursively measures the disk usage of @self.
1829 ///
1830 /// This is essentially an analog of the 'du' command, but it also
1831 /// reports the number of directories and non-directory files encountered
1832 /// (including things like symbolic links).
1833 ///
1834 /// By default, errors are only reported against the toplevel file
1835 /// itself. Errors found while recursing are silently ignored, unless
1836 /// [`FileMeasureFlags::REPORT_ANY_ERROR`][crate::FileMeasureFlags::REPORT_ANY_ERROR] is given in @flags.
1837 ///
1838 /// The returned size, @disk_usage, is in bytes and should be formatted
1839 /// with g_format_size() in order to get something reasonable for showing
1840 /// in a user interface.
1841 ///
1842 /// @progress_callback and @progress_data can be given to request
1843 /// periodic progress updates while scanning. See the documentation for
1844 /// #GFileMeasureProgressCallback for information about when and how the
1845 /// callback will be invoked.
1846 /// ## `flags`
1847 /// #GFileMeasureFlags
1848 /// ## `cancellable`
1849 /// optional #GCancellable
1850 /// ## `progress_callback`
1851 /// a #GFileMeasureProgressCallback
1852 /// ## `progress_data`
1853 /// user_data for @progress_callback
1854 ///
1855 /// # Returns
1856 ///
1857 /// [`true`] if successful, with the out parameters set.
1858 /// [`false`] otherwise, with @error set.
1859 ///
1860 /// ## `disk_usage`
1861 /// the number of bytes of disk space used
1862 ///
1863 /// ## `num_dirs`
1864 /// the number of directories encountered
1865 ///
1866 /// ## `num_files`
1867 /// the number of non-directories encountered
1868 #[doc(alias = "g_file_measure_disk_usage")]
1869 fn measure_disk_usage(
1870 &self,
1871 flags: FileMeasureFlags,
1872 cancellable: Option<&impl IsA<Cancellable>>,
1873 progress_callback: Option<&mut dyn FnMut(bool, u64, u64, u64)>,
1874 ) -> Result<(u64, u64, u64), glib::Error> {
1875 let mut progress_callback_data: Option<&mut dyn FnMut(bool, u64, u64, u64)> =
1876 progress_callback;
1877 unsafe extern "C" fn progress_callback_func(
1878 reporting: glib::ffi::gboolean,
1879 current_size: u64,
1880 num_dirs: u64,
1881 num_files: u64,
1882 data: glib::ffi::gpointer,
1883 ) {
1884 unsafe {
1885 let reporting = from_glib(reporting);
1886 let callback = data as *mut Option<&mut dyn FnMut(bool, u64, u64, u64)>;
1887 if let Some(ref mut callback) = *callback {
1888 callback(reporting, current_size, num_dirs, num_files)
1889 } else {
1890 panic!("cannot get closure...")
1891 }
1892 }
1893 }
1894 let progress_callback = if progress_callback_data.is_some() {
1895 Some(progress_callback_func as _)
1896 } else {
1897 None
1898 };
1899 let super_callback0: &mut Option<&mut dyn FnMut(bool, u64, u64, u64)> =
1900 &mut progress_callback_data;
1901 unsafe {
1902 let mut disk_usage = std::mem::MaybeUninit::uninit();
1903 let mut num_dirs = std::mem::MaybeUninit::uninit();
1904 let mut num_files = std::mem::MaybeUninit::uninit();
1905 let mut error = std::ptr::null_mut();
1906 let is_ok = ffi::g_file_measure_disk_usage(
1907 self.as_ref().to_glib_none().0,
1908 flags.into_glib(),
1909 cancellable.map(|p| p.as_ref()).to_glib_none().0,
1910 progress_callback,
1911 super_callback0 as *mut _ as *mut _,
1912 disk_usage.as_mut_ptr(),
1913 num_dirs.as_mut_ptr(),
1914 num_files.as_mut_ptr(),
1915 &mut error,
1916 );
1917 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
1918 if error.is_null() {
1919 Ok((
1920 disk_usage.assume_init(),
1921 num_dirs.assume_init(),
1922 num_files.assume_init(),
1923 ))
1924 } else {
1925 Err(from_glib_full(error))
1926 }
1927 }
1928 }
1929
1930 /// Obtains a file or directory monitor for the given file,
1931 /// depending on the type of the file.
1932 ///
1933 /// If @cancellable is not [`None`], then the operation can be cancelled by
1934 /// triggering the cancellable object from another thread. If the operation
1935 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
1936 /// ## `flags`
1937 /// a set of #GFileMonitorFlags
1938 /// ## `cancellable`
1939 /// optional #GCancellable object,
1940 /// [`None`] to ignore
1941 ///
1942 /// # Returns
1943 ///
1944 /// a #GFileMonitor for the given @self,
1945 /// or [`None`] on error.
1946 /// Free the returned object with g_object_unref().
1947 #[doc(alias = "g_file_monitor")]
1948 fn monitor(
1949 &self,
1950 flags: FileMonitorFlags,
1951 cancellable: Option<&impl IsA<Cancellable>>,
1952 ) -> Result<FileMonitor, glib::Error> {
1953 unsafe {
1954 let mut error = std::ptr::null_mut();
1955 let ret = ffi::g_file_monitor(
1956 self.as_ref().to_glib_none().0,
1957 flags.into_glib(),
1958 cancellable.map(|p| p.as_ref()).to_glib_none().0,
1959 &mut error,
1960 );
1961 if error.is_null() {
1962 Ok(from_glib_full(ret))
1963 } else {
1964 Err(from_glib_full(error))
1965 }
1966 }
1967 }
1968
1969 /// Obtains a directory monitor for the given file.
1970 /// This may fail if directory monitoring is not supported.
1971 ///
1972 /// If @cancellable is not [`None`], then the operation can be cancelled by
1973 /// triggering the cancellable object from another thread. If the operation
1974 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
1975 ///
1976 /// It does not make sense for @flags to contain
1977 /// [`FileMonitorFlags::WATCH_HARD_LINKS`][crate::FileMonitorFlags::WATCH_HARD_LINKS], since hard links can not be made to
1978 /// directories. It is not possible to monitor all the files in a
1979 /// directory for changes made via hard links; if you want to do this then
1980 /// you must register individual watches with g_file_monitor().
1981 /// ## `flags`
1982 /// a set of #GFileMonitorFlags
1983 /// ## `cancellable`
1984 /// optional #GCancellable object,
1985 /// [`None`] to ignore
1986 ///
1987 /// # Returns
1988 ///
1989 /// a #GFileMonitor for the given @self,
1990 /// or [`None`] on error. Free the returned object with g_object_unref().
1991 #[doc(alias = "g_file_monitor_directory")]
1992 fn monitor_directory(
1993 &self,
1994 flags: FileMonitorFlags,
1995 cancellable: Option<&impl IsA<Cancellable>>,
1996 ) -> Result<FileMonitor, glib::Error> {
1997 unsafe {
1998 let mut error = std::ptr::null_mut();
1999 let ret = ffi::g_file_monitor_directory(
2000 self.as_ref().to_glib_none().0,
2001 flags.into_glib(),
2002 cancellable.map(|p| p.as_ref()).to_glib_none().0,
2003 &mut error,
2004 );
2005 if error.is_null() {
2006 Ok(from_glib_full(ret))
2007 } else {
2008 Err(from_glib_full(error))
2009 }
2010 }
2011 }
2012
2013 /// Obtains a file monitor for the given file. If no file notification
2014 /// mechanism exists, then regular polling of the file is used.
2015 ///
2016 /// If @cancellable is not [`None`], then the operation can be cancelled by
2017 /// triggering the cancellable object from another thread. If the operation
2018 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
2019 ///
2020 /// If @flags contains [`FileMonitorFlags::WATCH_HARD_LINKS`][crate::FileMonitorFlags::WATCH_HARD_LINKS] then the monitor
2021 /// will also attempt to report changes made to the file via another
2022 /// filename (ie, a hard link). Without this flag, you can only rely on
2023 /// changes made through the filename contained in @self to be
2024 /// reported. Using this flag may result in an increase in resource
2025 /// usage, and may not have any effect depending on the #GFileMonitor
2026 /// backend and/or filesystem type.
2027 /// ## `flags`
2028 /// a set of #GFileMonitorFlags
2029 /// ## `cancellable`
2030 /// optional #GCancellable object,
2031 /// [`None`] to ignore
2032 ///
2033 /// # Returns
2034 ///
2035 /// a #GFileMonitor for the given @self,
2036 /// or [`None`] on error.
2037 /// Free the returned object with g_object_unref().
2038 #[doc(alias = "g_file_monitor_file")]
2039 fn monitor_file(
2040 &self,
2041 flags: FileMonitorFlags,
2042 cancellable: Option<&impl IsA<Cancellable>>,
2043 ) -> Result<FileMonitor, glib::Error> {
2044 unsafe {
2045 let mut error = std::ptr::null_mut();
2046 let ret = ffi::g_file_monitor_file(
2047 self.as_ref().to_glib_none().0,
2048 flags.into_glib(),
2049 cancellable.map(|p| p.as_ref()).to_glib_none().0,
2050 &mut error,
2051 );
2052 if error.is_null() {
2053 Ok(from_glib_full(ret))
2054 } else {
2055 Err(from_glib_full(error))
2056 }
2057 }
2058 }
2059
2060 /// Starts a @mount_operation, mounting the volume that contains
2061 /// the file @self.
2062 ///
2063 /// When this operation has completed, @callback will be called with
2064 /// @user_user data, and the operation can be finalized with
2065 /// g_file_mount_enclosing_volume_finish().
2066 ///
2067 /// If @cancellable is not [`None`], then the operation can be cancelled by
2068 /// triggering the cancellable object from another thread. If the operation
2069 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
2070 /// ## `flags`
2071 /// flags affecting the operation
2072 /// ## `mount_operation`
2073 /// a #GMountOperation
2074 /// or [`None`] to avoid user interaction
2075 /// ## `cancellable`
2076 /// optional #GCancellable object,
2077 /// [`None`] to ignore
2078 /// ## `callback`
2079 /// a #GAsyncReadyCallback to call
2080 /// when the request is satisfied, or [`None`]
2081 #[doc(alias = "g_file_mount_enclosing_volume")]
2082 fn mount_enclosing_volume<P: FnOnce(Result<(), glib::Error>) + 'static>(
2083 &self,
2084 flags: MountMountFlags,
2085 mount_operation: Option<&impl IsA<MountOperation>>,
2086 cancellable: Option<&impl IsA<Cancellable>>,
2087 callback: P,
2088 ) {
2089 let main_context = glib::MainContext::ref_thread_default();
2090 let is_main_context_owner = main_context.is_owner();
2091 let has_acquired_main_context = (!is_main_context_owner)
2092 .then(|| main_context.acquire().ok())
2093 .flatten();
2094 assert!(
2095 is_main_context_owner || has_acquired_main_context.is_some(),
2096 "Async operations only allowed if the thread is owning the MainContext"
2097 );
2098
2099 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
2100 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
2101 unsafe extern "C" fn mount_enclosing_volume_trampoline<
2102 P: FnOnce(Result<(), glib::Error>) + 'static,
2103 >(
2104 _source_object: *mut glib::gobject_ffi::GObject,
2105 res: *mut crate::ffi::GAsyncResult,
2106 user_data: glib::ffi::gpointer,
2107 ) {
2108 unsafe {
2109 let mut error = std::ptr::null_mut();
2110 ffi::g_file_mount_enclosing_volume_finish(
2111 _source_object as *mut _,
2112 res,
2113 &mut error,
2114 );
2115 let result = if error.is_null() {
2116 Ok(())
2117 } else {
2118 Err(from_glib_full(error))
2119 };
2120 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
2121 Box_::from_raw(user_data as *mut _);
2122 let callback: P = callback.into_inner();
2123 callback(result);
2124 }
2125 }
2126 let callback = mount_enclosing_volume_trampoline::<P>;
2127 unsafe {
2128 ffi::g_file_mount_enclosing_volume(
2129 self.as_ref().to_glib_none().0,
2130 flags.into_glib(),
2131 mount_operation.map(|p| p.as_ref()).to_glib_none().0,
2132 cancellable.map(|p| p.as_ref()).to_glib_none().0,
2133 Some(callback),
2134 Box_::into_raw(user_data) as *mut _,
2135 );
2136 }
2137 }
2138
2139 fn mount_enclosing_volume_future(
2140 &self,
2141 flags: MountMountFlags,
2142 mount_operation: Option<&(impl IsA<MountOperation> + Clone + 'static)>,
2143 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
2144 let mount_operation = mount_operation.map(ToOwned::to_owned);
2145 Box_::pin(crate::GioFuture::new(
2146 self,
2147 move |obj, cancellable, send| {
2148 obj.mount_enclosing_volume(
2149 flags,
2150 mount_operation.as_ref().map(::std::borrow::Borrow::borrow),
2151 Some(cancellable),
2152 move |res| {
2153 send.resolve(res);
2154 },
2155 );
2156 },
2157 ))
2158 }
2159
2160 /// Mounts a file of type G_FILE_TYPE_MOUNTABLE.
2161 /// Using @mount_operation, you can request callbacks when, for instance,
2162 /// passwords are needed during authentication.
2163 ///
2164 /// If @cancellable is not [`None`], then the operation can be cancelled by
2165 /// triggering the cancellable object from another thread. If the operation
2166 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
2167 ///
2168 /// When the operation is finished, @callback will be called.
2169 /// You can then call g_file_mount_mountable_finish() to get
2170 /// the result of the operation.
2171 /// ## `flags`
2172 /// flags affecting the operation
2173 /// ## `mount_operation`
2174 /// a #GMountOperation,
2175 /// or [`None`] to avoid user interaction
2176 /// ## `cancellable`
2177 /// optional #GCancellable object,
2178 /// [`None`] to ignore
2179 /// ## `callback`
2180 /// a #GAsyncReadyCallback
2181 /// to call when the request is satisfied
2182 #[doc(alias = "g_file_mount_mountable")]
2183 fn mount_mountable<P: FnOnce(Result<File, glib::Error>) + 'static>(
2184 &self,
2185 flags: MountMountFlags,
2186 mount_operation: Option<&impl IsA<MountOperation>>,
2187 cancellable: Option<&impl IsA<Cancellable>>,
2188 callback: P,
2189 ) {
2190 let main_context = glib::MainContext::ref_thread_default();
2191 let is_main_context_owner = main_context.is_owner();
2192 let has_acquired_main_context = (!is_main_context_owner)
2193 .then(|| main_context.acquire().ok())
2194 .flatten();
2195 assert!(
2196 is_main_context_owner || has_acquired_main_context.is_some(),
2197 "Async operations only allowed if the thread is owning the MainContext"
2198 );
2199
2200 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
2201 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
2202 unsafe extern "C" fn mount_mountable_trampoline<
2203 P: FnOnce(Result<File, glib::Error>) + 'static,
2204 >(
2205 _source_object: *mut glib::gobject_ffi::GObject,
2206 res: *mut crate::ffi::GAsyncResult,
2207 user_data: glib::ffi::gpointer,
2208 ) {
2209 unsafe {
2210 let mut error = std::ptr::null_mut();
2211 let ret =
2212 ffi::g_file_mount_mountable_finish(_source_object as *mut _, res, &mut error);
2213 let result = if error.is_null() {
2214 Ok(from_glib_full(ret))
2215 } else {
2216 Err(from_glib_full(error))
2217 };
2218 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
2219 Box_::from_raw(user_data as *mut _);
2220 let callback: P = callback.into_inner();
2221 callback(result);
2222 }
2223 }
2224 let callback = mount_mountable_trampoline::<P>;
2225 unsafe {
2226 ffi::g_file_mount_mountable(
2227 self.as_ref().to_glib_none().0,
2228 flags.into_glib(),
2229 mount_operation.map(|p| p.as_ref()).to_glib_none().0,
2230 cancellable.map(|p| p.as_ref()).to_glib_none().0,
2231 Some(callback),
2232 Box_::into_raw(user_data) as *mut _,
2233 );
2234 }
2235 }
2236
2237 fn mount_mountable_future(
2238 &self,
2239 flags: MountMountFlags,
2240 mount_operation: Option<&(impl IsA<MountOperation> + Clone + 'static)>,
2241 ) -> Pin<Box_<dyn std::future::Future<Output = Result<File, glib::Error>> + 'static>> {
2242 let mount_operation = mount_operation.map(ToOwned::to_owned);
2243 Box_::pin(crate::GioFuture::new(
2244 self,
2245 move |obj, cancellable, send| {
2246 obj.mount_mountable(
2247 flags,
2248 mount_operation.as_ref().map(::std::borrow::Borrow::borrow),
2249 Some(cancellable),
2250 move |res| {
2251 send.resolve(res);
2252 },
2253 );
2254 },
2255 ))
2256 }
2257
2258 /// Tries to move the file or directory @self to the location specified
2259 /// by @destination. If native move operations are supported then this is
2260 /// used, otherwise a copy + delete fallback is used. The native
2261 /// implementation may support moving directories (for instance on moves
2262 /// inside the same filesystem), but the fallback code does not.
2263 ///
2264 /// If the flag [`FileCopyFlags::OVERWRITE`][crate::FileCopyFlags::OVERWRITE] is specified an already
2265 /// existing @destination file is overwritten.
2266 ///
2267 /// If @cancellable is not [`None`], then the operation can be cancelled by
2268 /// triggering the cancellable object from another thread. If the operation
2269 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
2270 ///
2271 /// If @progress_callback is not [`None`], then the operation can be monitored
2272 /// by setting this to a #GFileProgressCallback function.
2273 /// @progress_callback_data will be passed to this function. It is
2274 /// guaranteed that this callback will be called after all data has been
2275 /// transferred with the total number of bytes copied during the operation.
2276 ///
2277 /// If the @self file does not exist, then the [`IOErrorEnum::NotFound`][crate::IOErrorEnum::NotFound]
2278 /// error is returned, independent on the status of the @destination.
2279 ///
2280 /// If [`FileCopyFlags::OVERWRITE`][crate::FileCopyFlags::OVERWRITE] is not specified and the target exists,
2281 /// then the error [`IOErrorEnum::Exists`][crate::IOErrorEnum::Exists] is returned.
2282 ///
2283 /// If trying to overwrite a file over a directory, the [`IOErrorEnum::IsDirectory`][crate::IOErrorEnum::IsDirectory]
2284 /// error is returned. If trying to overwrite a directory with a directory the
2285 /// [`IOErrorEnum::WouldMerge`][crate::IOErrorEnum::WouldMerge] error is returned.
2286 ///
2287 /// If the source is a directory and the target does not exist, or
2288 /// [`FileCopyFlags::OVERWRITE`][crate::FileCopyFlags::OVERWRITE] is specified and the target is a file, then
2289 /// the [`IOErrorEnum::WouldRecurse`][crate::IOErrorEnum::WouldRecurse] error may be returned (if the native
2290 /// move operation isn't available).
2291 /// ## `destination`
2292 /// #GFile pointing to the destination location
2293 /// ## `flags`
2294 /// set of #GFileCopyFlags
2295 /// ## `cancellable`
2296 /// optional #GCancellable object,
2297 /// [`None`] to ignore
2298 /// ## `progress_callback`
2299 /// #GFileProgressCallback
2300 /// function for updates
2301 /// ## `progress_callback_data`
2302 /// gpointer to user data for
2303 /// the callback function
2304 ///
2305 /// # Returns
2306 ///
2307 /// [`true`] on successful move, [`false`] otherwise.
2308 #[doc(alias = "g_file_move")]
2309 #[doc(alias = "move")]
2310 fn move_(
2311 &self,
2312 destination: &impl IsA<File>,
2313 flags: FileCopyFlags,
2314 cancellable: Option<&impl IsA<Cancellable>>,
2315 progress_callback: Option<&mut dyn FnMut(i64, i64)>,
2316 ) -> Result<(), glib::Error> {
2317 let mut progress_callback_data: Option<&mut dyn FnMut(i64, i64)> = progress_callback;
2318 unsafe extern "C" fn progress_callback_func(
2319 current_num_bytes: i64,
2320 total_num_bytes: i64,
2321 data: glib::ffi::gpointer,
2322 ) {
2323 unsafe {
2324 let callback = data as *mut Option<&mut dyn FnMut(i64, i64)>;
2325 if let Some(ref mut callback) = *callback {
2326 callback(current_num_bytes, total_num_bytes)
2327 } else {
2328 panic!("cannot get closure...")
2329 }
2330 }
2331 }
2332 let progress_callback = if progress_callback_data.is_some() {
2333 Some(progress_callback_func as _)
2334 } else {
2335 None
2336 };
2337 let super_callback0: &mut Option<&mut dyn FnMut(i64, i64)> = &mut progress_callback_data;
2338 unsafe {
2339 let mut error = std::ptr::null_mut();
2340 let is_ok = ffi::g_file_move(
2341 self.as_ref().to_glib_none().0,
2342 destination.as_ref().to_glib_none().0,
2343 flags.into_glib(),
2344 cancellable.map(|p| p.as_ref()).to_glib_none().0,
2345 progress_callback,
2346 super_callback0 as *mut _ as *mut _,
2347 &mut error,
2348 );
2349 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
2350 if error.is_null() {
2351 Ok(())
2352 } else {
2353 Err(from_glib_full(error))
2354 }
2355 }
2356 }
2357
2358 /// Opens an existing file for reading and writing. The result is
2359 /// a #GFileIOStream that can be used to read and write the contents
2360 /// of the file.
2361 ///
2362 /// If @cancellable is not [`None`], then the operation can be cancelled
2363 /// by triggering the cancellable object from another thread. If the
2364 /// operation was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be
2365 /// returned.
2366 ///
2367 /// If the file does not exist, the [`IOErrorEnum::NotFound`][crate::IOErrorEnum::NotFound] error will
2368 /// be returned. If the file is a directory, the [`IOErrorEnum::IsDirectory`][crate::IOErrorEnum::IsDirectory]
2369 /// error will be returned. Other errors are possible too, and depend on
2370 /// what kind of filesystem the file is on. Note that in many non-local
2371 /// file cases read and write streams are not supported, so make sure you
2372 /// really need to do read and write streaming, rather than just opening
2373 /// for reading or writing.
2374 /// ## `cancellable`
2375 /// a #GCancellable
2376 ///
2377 /// # Returns
2378 ///
2379 /// #GFileIOStream or [`None`] on error.
2380 /// Free the returned object with g_object_unref().
2381 #[doc(alias = "g_file_open_readwrite")]
2382 fn open_readwrite(
2383 &self,
2384 cancellable: Option<&impl IsA<Cancellable>>,
2385 ) -> Result<FileIOStream, glib::Error> {
2386 unsafe {
2387 let mut error = std::ptr::null_mut();
2388 let ret = ffi::g_file_open_readwrite(
2389 self.as_ref().to_glib_none().0,
2390 cancellable.map(|p| p.as_ref()).to_glib_none().0,
2391 &mut error,
2392 );
2393 if error.is_null() {
2394 Ok(from_glib_full(ret))
2395 } else {
2396 Err(from_glib_full(error))
2397 }
2398 }
2399 }
2400
2401 /// Asynchronously opens @self for reading and writing.
2402 ///
2403 /// For more details, see g_file_open_readwrite() which is
2404 /// the synchronous version of this call.
2405 ///
2406 /// When the operation is finished, @callback will be called.
2407 /// You can then call g_file_open_readwrite_finish() to get
2408 /// the result of the operation.
2409 /// ## `io_priority`
2410 /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
2411 /// ## `cancellable`
2412 /// optional #GCancellable object,
2413 /// [`None`] to ignore
2414 /// ## `callback`
2415 /// a #GAsyncReadyCallback
2416 /// to call when the request is satisfied
2417 #[doc(alias = "g_file_open_readwrite_async")]
2418 fn open_readwrite_async<P: FnOnce(Result<FileIOStream, glib::Error>) + 'static>(
2419 &self,
2420 io_priority: glib::Priority,
2421 cancellable: Option<&impl IsA<Cancellable>>,
2422 callback: P,
2423 ) {
2424 let main_context = glib::MainContext::ref_thread_default();
2425 let is_main_context_owner = main_context.is_owner();
2426 let has_acquired_main_context = (!is_main_context_owner)
2427 .then(|| main_context.acquire().ok())
2428 .flatten();
2429 assert!(
2430 is_main_context_owner || has_acquired_main_context.is_some(),
2431 "Async operations only allowed if the thread is owning the MainContext"
2432 );
2433
2434 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
2435 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
2436 unsafe extern "C" fn open_readwrite_async_trampoline<
2437 P: FnOnce(Result<FileIOStream, glib::Error>) + 'static,
2438 >(
2439 _source_object: *mut glib::gobject_ffi::GObject,
2440 res: *mut crate::ffi::GAsyncResult,
2441 user_data: glib::ffi::gpointer,
2442 ) {
2443 unsafe {
2444 let mut error = std::ptr::null_mut();
2445 let ret =
2446 ffi::g_file_open_readwrite_finish(_source_object as *mut _, res, &mut error);
2447 let result = if error.is_null() {
2448 Ok(from_glib_full(ret))
2449 } else {
2450 Err(from_glib_full(error))
2451 };
2452 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
2453 Box_::from_raw(user_data as *mut _);
2454 let callback: P = callback.into_inner();
2455 callback(result);
2456 }
2457 }
2458 let callback = open_readwrite_async_trampoline::<P>;
2459 unsafe {
2460 ffi::g_file_open_readwrite_async(
2461 self.as_ref().to_glib_none().0,
2462 io_priority.into_glib(),
2463 cancellable.map(|p| p.as_ref()).to_glib_none().0,
2464 Some(callback),
2465 Box_::into_raw(user_data) as *mut _,
2466 );
2467 }
2468 }
2469
2470 fn open_readwrite_future(
2471 &self,
2472 io_priority: glib::Priority,
2473 ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileIOStream, glib::Error>> + 'static>>
2474 {
2475 Box_::pin(crate::GioFuture::new(
2476 self,
2477 move |obj, cancellable, send| {
2478 obj.open_readwrite_async(io_priority, Some(cancellable), move |res| {
2479 send.resolve(res);
2480 });
2481 },
2482 ))
2483 }
2484
2485 /// Exactly like g_file_get_path(), but caches the result via
2486 /// g_object_set_qdata_full(). This is useful for example in C
2487 /// applications which mix `g_file_*` APIs with native ones. It
2488 /// also avoids an extra duplicated string when possible, so will be
2489 /// generally more efficient.
2490 ///
2491 /// This call does no blocking I/O.
2492 ///
2493 /// # Returns
2494 ///
2495 /// string containing the #GFile's path,
2496 /// or [`None`] if no such path exists. The returned string is owned by @self.
2497 #[doc(alias = "g_file_peek_path")]
2498 fn peek_path(&self) -> Option<std::path::PathBuf> {
2499 unsafe { from_glib_none(ffi::g_file_peek_path(self.as_ref().to_glib_none().0)) }
2500 }
2501
2502 /// Polls a file of type [`FileType::Mountable`][crate::FileType::Mountable].
2503 ///
2504 /// If @cancellable is not [`None`], then the operation can be cancelled by
2505 /// triggering the cancellable object from another thread. If the operation
2506 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
2507 ///
2508 /// When the operation is finished, @callback will be called.
2509 /// You can then call g_file_mount_mountable_finish() to get
2510 /// the result of the operation.
2511 /// ## `cancellable`
2512 /// optional #GCancellable object, [`None`] to ignore
2513 /// ## `callback`
2514 /// a #GAsyncReadyCallback to call
2515 /// when the request is satisfied, or [`None`]
2516 #[doc(alias = "g_file_poll_mountable")]
2517 fn poll_mountable<P: FnOnce(Result<(), glib::Error>) + 'static>(
2518 &self,
2519 cancellable: Option<&impl IsA<Cancellable>>,
2520 callback: P,
2521 ) {
2522 let main_context = glib::MainContext::ref_thread_default();
2523 let is_main_context_owner = main_context.is_owner();
2524 let has_acquired_main_context = (!is_main_context_owner)
2525 .then(|| main_context.acquire().ok())
2526 .flatten();
2527 assert!(
2528 is_main_context_owner || has_acquired_main_context.is_some(),
2529 "Async operations only allowed if the thread is owning the MainContext"
2530 );
2531
2532 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
2533 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
2534 unsafe extern "C" fn poll_mountable_trampoline<
2535 P: FnOnce(Result<(), glib::Error>) + 'static,
2536 >(
2537 _source_object: *mut glib::gobject_ffi::GObject,
2538 res: *mut crate::ffi::GAsyncResult,
2539 user_data: glib::ffi::gpointer,
2540 ) {
2541 unsafe {
2542 let mut error = std::ptr::null_mut();
2543 ffi::g_file_poll_mountable_finish(_source_object as *mut _, res, &mut error);
2544 let result = if error.is_null() {
2545 Ok(())
2546 } else {
2547 Err(from_glib_full(error))
2548 };
2549 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
2550 Box_::from_raw(user_data as *mut _);
2551 let callback: P = callback.into_inner();
2552 callback(result);
2553 }
2554 }
2555 let callback = poll_mountable_trampoline::<P>;
2556 unsafe {
2557 ffi::g_file_poll_mountable(
2558 self.as_ref().to_glib_none().0,
2559 cancellable.map(|p| p.as_ref()).to_glib_none().0,
2560 Some(callback),
2561 Box_::into_raw(user_data) as *mut _,
2562 );
2563 }
2564 }
2565
2566 fn poll_mountable_future(
2567 &self,
2568 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
2569 Box_::pin(crate::GioFuture::new(
2570 self,
2571 move |obj, cancellable, send| {
2572 obj.poll_mountable(Some(cancellable), move |res| {
2573 send.resolve(res);
2574 });
2575 },
2576 ))
2577 }
2578
2579 /// Returns the #GAppInfo that is registered as the default
2580 /// application to handle the file specified by @self.
2581 ///
2582 /// If @cancellable is not [`None`], then the operation can be cancelled by
2583 /// triggering the cancellable object from another thread. If the operation
2584 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
2585 /// ## `cancellable`
2586 /// optional #GCancellable object, [`None`] to ignore
2587 ///
2588 /// # Returns
2589 ///
2590 /// a #GAppInfo if the handle was found,
2591 /// [`None`] if there were errors.
2592 /// When you are done with it, release it with g_object_unref()
2593 #[doc(alias = "g_file_query_default_handler")]
2594 fn query_default_handler(
2595 &self,
2596 cancellable: Option<&impl IsA<Cancellable>>,
2597 ) -> Result<AppInfo, glib::Error> {
2598 unsafe {
2599 let mut error = std::ptr::null_mut();
2600 let ret = ffi::g_file_query_default_handler(
2601 self.as_ref().to_glib_none().0,
2602 cancellable.map(|p| p.as_ref()).to_glib_none().0,
2603 &mut error,
2604 );
2605 if error.is_null() {
2606 Ok(from_glib_full(ret))
2607 } else {
2608 Err(from_glib_full(error))
2609 }
2610 }
2611 }
2612
2613 /// Async version of g_file_query_default_handler().
2614 /// ## `io_priority`
2615 /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
2616 /// ## `cancellable`
2617 /// optional #GCancellable object, [`None`] to ignore
2618 /// ## `callback`
2619 /// a #GAsyncReadyCallback to call when the request is done
2620 #[cfg(feature = "v2_60")]
2621 #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
2622 #[doc(alias = "g_file_query_default_handler_async")]
2623 fn query_default_handler_async<P: FnOnce(Result<AppInfo, glib::Error>) + 'static>(
2624 &self,
2625 io_priority: glib::Priority,
2626 cancellable: Option<&impl IsA<Cancellable>>,
2627 callback: P,
2628 ) {
2629 let main_context = glib::MainContext::ref_thread_default();
2630 let is_main_context_owner = main_context.is_owner();
2631 let has_acquired_main_context = (!is_main_context_owner)
2632 .then(|| main_context.acquire().ok())
2633 .flatten();
2634 assert!(
2635 is_main_context_owner || has_acquired_main_context.is_some(),
2636 "Async operations only allowed if the thread is owning the MainContext"
2637 );
2638
2639 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
2640 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
2641 unsafe extern "C" fn query_default_handler_async_trampoline<
2642 P: FnOnce(Result<AppInfo, glib::Error>) + 'static,
2643 >(
2644 _source_object: *mut glib::gobject_ffi::GObject,
2645 res: *mut crate::ffi::GAsyncResult,
2646 user_data: glib::ffi::gpointer,
2647 ) {
2648 unsafe {
2649 let mut error = std::ptr::null_mut();
2650 let ret = ffi::g_file_query_default_handler_finish(
2651 _source_object as *mut _,
2652 res,
2653 &mut error,
2654 );
2655 let result = if error.is_null() {
2656 Ok(from_glib_full(ret))
2657 } else {
2658 Err(from_glib_full(error))
2659 };
2660 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
2661 Box_::from_raw(user_data as *mut _);
2662 let callback: P = callback.into_inner();
2663 callback(result);
2664 }
2665 }
2666 let callback = query_default_handler_async_trampoline::<P>;
2667 unsafe {
2668 ffi::g_file_query_default_handler_async(
2669 self.as_ref().to_glib_none().0,
2670 io_priority.into_glib(),
2671 cancellable.map(|p| p.as_ref()).to_glib_none().0,
2672 Some(callback),
2673 Box_::into_raw(user_data) as *mut _,
2674 );
2675 }
2676 }
2677
2678 #[cfg(feature = "v2_60")]
2679 #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
2680 fn query_default_handler_future(
2681 &self,
2682 io_priority: glib::Priority,
2683 ) -> Pin<Box_<dyn std::future::Future<Output = Result<AppInfo, glib::Error>> + 'static>> {
2684 Box_::pin(crate::GioFuture::new(
2685 self,
2686 move |obj, cancellable, send| {
2687 obj.query_default_handler_async(io_priority, Some(cancellable), move |res| {
2688 send.resolve(res);
2689 });
2690 },
2691 ))
2692 }
2693
2694 /// Utility function to check if a particular file exists.
2695 ///
2696 /// The fallback implementation of this API is using [`query_info()`][Self::query_info()]
2697 /// and therefore may do blocking I/O. To asynchronously query the existence
2698 /// of a file, use [`query_info_async()`][Self::query_info_async()].
2699 ///
2700 /// Note that in many cases it is [racy to first check for file existence](https://en.wikipedia.org/wiki/Time_of_check_to_time_of_use)
2701 /// and then execute something based on the outcome of that, because the
2702 /// file might have been created or removed in between the operations. The
2703 /// general approach to handling that is to not check, but just do the
2704 /// operation and handle the errors as they come.
2705 ///
2706 /// As an example of race-free checking, take the case of reading a file,
2707 /// and if it doesn't exist, creating it. There are two racy versions: read
2708 /// it, and on error create it; and: check if it exists, if not create it.
2709 /// These can both result in two processes creating the file (with perhaps
2710 /// a partially written file as the result). The correct approach is to
2711 /// always try to create the file with g_file_create() which will either
2712 /// atomically create the file or fail with a [`IOErrorEnum::Exists`][crate::IOErrorEnum::Exists] error.
2713 ///
2714 /// However, in many cases an existence check is useful in a user interface,
2715 /// for instance to make a menu item sensitive/insensitive, so that you don't
2716 /// have to fool users that something is possible and then just show an error
2717 /// dialog. If you do this, you should make sure to also handle the errors
2718 /// that can happen due to races when you execute the operation.
2719 /// ## `cancellable`
2720 /// optional #GCancellable object,
2721 /// [`None`] to ignore
2722 ///
2723 /// # Returns
2724 ///
2725 /// [`true`] if the file exists (and can be detected without error),
2726 /// [`false`] otherwise (or if cancelled).
2727 #[doc(alias = "g_file_query_exists")]
2728 fn query_exists(&self, cancellable: Option<&impl IsA<Cancellable>>) -> bool {
2729 unsafe {
2730 from_glib(ffi::g_file_query_exists(
2731 self.as_ref().to_glib_none().0,
2732 cancellable.map(|p| p.as_ref()).to_glib_none().0,
2733 ))
2734 }
2735 }
2736
2737 /// Utility function to inspect the #GFileType of a file. This is
2738 /// implemented using g_file_query_info() and as such does blocking I/O.
2739 ///
2740 /// The primary use case of this method is to check if a file is
2741 /// a regular file, directory, or symlink.
2742 /// ## `flags`
2743 /// a set of #GFileQueryInfoFlags passed to g_file_query_info()
2744 /// ## `cancellable`
2745 /// optional #GCancellable object,
2746 /// [`None`] to ignore
2747 ///
2748 /// # Returns
2749 ///
2750 /// The #GFileType of the file and [`FileType::Unknown`][crate::FileType::Unknown]
2751 /// if the file does not exist
2752 #[doc(alias = "g_file_query_file_type")]
2753 fn query_file_type(
2754 &self,
2755 flags: FileQueryInfoFlags,
2756 cancellable: Option<&impl IsA<Cancellable>>,
2757 ) -> FileType {
2758 unsafe {
2759 from_glib(ffi::g_file_query_file_type(
2760 self.as_ref().to_glib_none().0,
2761 flags.into_glib(),
2762 cancellable.map(|p| p.as_ref()).to_glib_none().0,
2763 ))
2764 }
2765 }
2766
2767 /// Similar to g_file_query_info(), but obtains information
2768 /// about the filesystem the @self is on, rather than the file itself.
2769 /// For instance the amount of space available and the type of
2770 /// the filesystem.
2771 ///
2772 /// The @attributes value is a string that specifies the attributes
2773 /// that should be gathered. It is not an error if it's not possible
2774 /// to read a particular requested attribute from a file - it just
2775 /// won't be set. @attributes should be a comma-separated list of
2776 /// attributes or attribute wildcards. The wildcard "\*" means all
2777 /// attributes, and a wildcard like "filesystem::*" means all attributes
2778 /// in the filesystem namespace. The standard namespace for filesystem
2779 /// attributes is "filesystem". Common attributes of interest are
2780 /// [`FILE_ATTRIBUTE_FILESYSTEM_SIZE`][crate::FILE_ATTRIBUTE_FILESYSTEM_SIZE] (the total size of the filesystem
2781 /// in bytes), [`FILE_ATTRIBUTE_FILESYSTEM_FREE`][crate::FILE_ATTRIBUTE_FILESYSTEM_FREE] (number of bytes available),
2782 /// and [`FILE_ATTRIBUTE_FILESYSTEM_TYPE`][crate::FILE_ATTRIBUTE_FILESYSTEM_TYPE] (type of the filesystem).
2783 ///
2784 /// If @cancellable is not [`None`], then the operation can be cancelled
2785 /// by triggering the cancellable object from another thread. If the
2786 /// operation was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be
2787 /// returned.
2788 ///
2789 /// If the file does not exist, the [`IOErrorEnum::NotFound`][crate::IOErrorEnum::NotFound] error will
2790 /// be returned. Other errors are possible too, and depend on what
2791 /// kind of filesystem the file is on.
2792 /// ## `attributes`
2793 /// an attribute query string
2794 /// ## `cancellable`
2795 /// optional #GCancellable object,
2796 /// [`None`] to ignore
2797 ///
2798 /// # Returns
2799 ///
2800 /// a #GFileInfo or [`None`] if there was an error.
2801 /// Free the returned object with g_object_unref().
2802 #[doc(alias = "g_file_query_filesystem_info")]
2803 fn query_filesystem_info(
2804 &self,
2805 attributes: &str,
2806 cancellable: Option<&impl IsA<Cancellable>>,
2807 ) -> Result<FileInfo, glib::Error> {
2808 unsafe {
2809 let mut error = std::ptr::null_mut();
2810 let ret = ffi::g_file_query_filesystem_info(
2811 self.as_ref().to_glib_none().0,
2812 attributes.to_glib_none().0,
2813 cancellable.map(|p| p.as_ref()).to_glib_none().0,
2814 &mut error,
2815 );
2816 if error.is_null() {
2817 Ok(from_glib_full(ret))
2818 } else {
2819 Err(from_glib_full(error))
2820 }
2821 }
2822 }
2823
2824 /// Asynchronously gets the requested information about the filesystem
2825 /// that the specified @self is on. The result is a #GFileInfo object
2826 /// that contains key-value attributes (such as type or size for the
2827 /// file).
2828 ///
2829 /// For more details, see g_file_query_filesystem_info() which is the
2830 /// synchronous version of this call.
2831 ///
2832 /// When the operation is finished, @callback will be called. You can
2833 /// then call g_file_query_info_finish() to get the result of the
2834 /// operation.
2835 /// ## `attributes`
2836 /// an attribute query string
2837 /// ## `io_priority`
2838 /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
2839 /// ## `cancellable`
2840 /// optional #GCancellable object,
2841 /// [`None`] to ignore
2842 /// ## `callback`
2843 /// a #GAsyncReadyCallback
2844 /// to call when the request is satisfied
2845 #[doc(alias = "g_file_query_filesystem_info_async")]
2846 fn query_filesystem_info_async<P: FnOnce(Result<FileInfo, glib::Error>) + 'static>(
2847 &self,
2848 attributes: &str,
2849 io_priority: glib::Priority,
2850 cancellable: Option<&impl IsA<Cancellable>>,
2851 callback: P,
2852 ) {
2853 let main_context = glib::MainContext::ref_thread_default();
2854 let is_main_context_owner = main_context.is_owner();
2855 let has_acquired_main_context = (!is_main_context_owner)
2856 .then(|| main_context.acquire().ok())
2857 .flatten();
2858 assert!(
2859 is_main_context_owner || has_acquired_main_context.is_some(),
2860 "Async operations only allowed if the thread is owning the MainContext"
2861 );
2862
2863 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
2864 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
2865 unsafe extern "C" fn query_filesystem_info_async_trampoline<
2866 P: FnOnce(Result<FileInfo, glib::Error>) + 'static,
2867 >(
2868 _source_object: *mut glib::gobject_ffi::GObject,
2869 res: *mut crate::ffi::GAsyncResult,
2870 user_data: glib::ffi::gpointer,
2871 ) {
2872 unsafe {
2873 let mut error = std::ptr::null_mut();
2874 let ret = ffi::g_file_query_filesystem_info_finish(
2875 _source_object as *mut _,
2876 res,
2877 &mut error,
2878 );
2879 let result = if error.is_null() {
2880 Ok(from_glib_full(ret))
2881 } else {
2882 Err(from_glib_full(error))
2883 };
2884 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
2885 Box_::from_raw(user_data as *mut _);
2886 let callback: P = callback.into_inner();
2887 callback(result);
2888 }
2889 }
2890 let callback = query_filesystem_info_async_trampoline::<P>;
2891 unsafe {
2892 ffi::g_file_query_filesystem_info_async(
2893 self.as_ref().to_glib_none().0,
2894 attributes.to_glib_none().0,
2895 io_priority.into_glib(),
2896 cancellable.map(|p| p.as_ref()).to_glib_none().0,
2897 Some(callback),
2898 Box_::into_raw(user_data) as *mut _,
2899 );
2900 }
2901 }
2902
2903 fn query_filesystem_info_future(
2904 &self,
2905 attributes: &str,
2906 io_priority: glib::Priority,
2907 ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileInfo, glib::Error>> + 'static>> {
2908 let attributes = String::from(attributes);
2909 Box_::pin(crate::GioFuture::new(
2910 self,
2911 move |obj, cancellable, send| {
2912 obj.query_filesystem_info_async(
2913 &attributes,
2914 io_priority,
2915 Some(cancellable),
2916 move |res| {
2917 send.resolve(res);
2918 },
2919 );
2920 },
2921 ))
2922 }
2923
2924 /// Gets the requested information about specified @self.
2925 ///
2926 /// The result is a [`FileInfo`][crate::FileInfo] object that contains key-value
2927 /// attributes (such as the type or size of the file).
2928 ///
2929 /// The @attributes value is a string that specifies the file
2930 /// attributes that should be gathered. It is not an error if
2931 /// it’s not possible to read a particular requested attribute
2932 /// from a file — it just won't be set. In particular this means that if a file
2933 /// is inaccessible (due to being in a folder with restrictive permissions), for
2934 /// example, you can expect the returned [`FileInfo`][crate::FileInfo] to have very few
2935 /// attributes set. You should check whether an attribute is set using
2936 /// [`FileInfo::has_attribute()`][crate::FileInfo::has_attribute()] before trying to retrieve its value.
2937 ///
2938 /// It is guaranteed that if any of the following attributes are listed in
2939 /// @attributes, they will always be set in the returned [`FileInfo`][crate::FileInfo],
2940 /// even if the user doesn’t have permissions to access the file:
2941 ///
2942 /// - `Gio::FILE_ATTRIBUTE_STANDARD_NAME`
2943 /// - `Gio::FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME`
2944 ///
2945 /// @attributes should be a comma-separated list of attributes or attribute
2946 /// wildcards. The wildcard `"\*"` means all attributes, and a wildcard like
2947 /// `"standard::*"` means all attributes in the standard namespace.
2948 /// An example attribute query might be `"standard::*,owner::user"`.
2949 /// The standard attributes are available as defines, like
2950 /// `Gio::FILE_ATTRIBUTE_STANDARD_NAME`.
2951 ///
2952 /// If @cancellable is not `NULL`, then the operation can be cancelled
2953 /// by triggering the cancellable object from another thread. If the
2954 /// operation was cancelled, the error [error@Gio.IOErrorEnum.CANCELLED] will be
2955 /// returned.
2956 ///
2957 /// For symlinks, normally the information about the target of the
2958 /// symlink is returned, rather than information about the symlink
2959 /// itself. However if you pass [flags@Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS]
2960 /// in @flags the information about the symlink itself will be returned.
2961 /// Also, for symlinks that point to non-existing files the information
2962 /// about the symlink itself will be returned.
2963 ///
2964 /// If the file does not exist, the [error@Gio.IOErrorEnum.NOT_FOUND] error will be
2965 /// returned. Other errors are possible too, and depend on what kind of
2966 /// file system the file is on.
2967 /// ## `attributes`
2968 /// an attribute query string
2969 /// ## `flags`
2970 /// flags to affect the query operation
2971 /// ## `cancellable`
2972 /// optional cancellable object
2973 ///
2974 /// # Returns
2975 ///
2976 /// a [`FileInfo`][crate::FileInfo] for the given @self
2977 #[doc(alias = "g_file_query_info")]
2978 fn query_info(
2979 &self,
2980 attributes: &str,
2981 flags: FileQueryInfoFlags,
2982 cancellable: Option<&impl IsA<Cancellable>>,
2983 ) -> Result<FileInfo, glib::Error> {
2984 unsafe {
2985 let mut error = std::ptr::null_mut();
2986 let ret = ffi::g_file_query_info(
2987 self.as_ref().to_glib_none().0,
2988 attributes.to_glib_none().0,
2989 flags.into_glib(),
2990 cancellable.map(|p| p.as_ref()).to_glib_none().0,
2991 &mut error,
2992 );
2993 if error.is_null() {
2994 Ok(from_glib_full(ret))
2995 } else {
2996 Err(from_glib_full(error))
2997 }
2998 }
2999 }
3000
3001 /// Asynchronously gets the requested information about specified @self.
3002 /// The result is a #GFileInfo object that contains key-value attributes
3003 /// (such as type or size for the file).
3004 ///
3005 /// For more details, see g_file_query_info() which is the synchronous
3006 /// version of this call.
3007 ///
3008 /// When the operation is finished, @callback will be called. You can
3009 /// then call g_file_query_info_finish() to get the result of the operation.
3010 /// ## `attributes`
3011 /// an attribute query string
3012 /// ## `flags`
3013 /// a set of #GFileQueryInfoFlags
3014 /// ## `io_priority`
3015 /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
3016 /// ## `cancellable`
3017 /// optional #GCancellable object,
3018 /// [`None`] to ignore
3019 /// ## `callback`
3020 /// a #GAsyncReadyCallback
3021 /// to call when the request is satisfied
3022 #[doc(alias = "g_file_query_info_async")]
3023 fn query_info_async<P: FnOnce(Result<FileInfo, glib::Error>) + 'static>(
3024 &self,
3025 attributes: &str,
3026 flags: FileQueryInfoFlags,
3027 io_priority: glib::Priority,
3028 cancellable: Option<&impl IsA<Cancellable>>,
3029 callback: P,
3030 ) {
3031 let main_context = glib::MainContext::ref_thread_default();
3032 let is_main_context_owner = main_context.is_owner();
3033 let has_acquired_main_context = (!is_main_context_owner)
3034 .then(|| main_context.acquire().ok())
3035 .flatten();
3036 assert!(
3037 is_main_context_owner || has_acquired_main_context.is_some(),
3038 "Async operations only allowed if the thread is owning the MainContext"
3039 );
3040
3041 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
3042 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
3043 unsafe extern "C" fn query_info_async_trampoline<
3044 P: FnOnce(Result<FileInfo, glib::Error>) + 'static,
3045 >(
3046 _source_object: *mut glib::gobject_ffi::GObject,
3047 res: *mut crate::ffi::GAsyncResult,
3048 user_data: glib::ffi::gpointer,
3049 ) {
3050 unsafe {
3051 let mut error = std::ptr::null_mut();
3052 let ret = ffi::g_file_query_info_finish(_source_object as *mut _, res, &mut error);
3053 let result = if error.is_null() {
3054 Ok(from_glib_full(ret))
3055 } else {
3056 Err(from_glib_full(error))
3057 };
3058 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
3059 Box_::from_raw(user_data as *mut _);
3060 let callback: P = callback.into_inner();
3061 callback(result);
3062 }
3063 }
3064 let callback = query_info_async_trampoline::<P>;
3065 unsafe {
3066 ffi::g_file_query_info_async(
3067 self.as_ref().to_glib_none().0,
3068 attributes.to_glib_none().0,
3069 flags.into_glib(),
3070 io_priority.into_glib(),
3071 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3072 Some(callback),
3073 Box_::into_raw(user_data) as *mut _,
3074 );
3075 }
3076 }
3077
3078 fn query_info_future(
3079 &self,
3080 attributes: &str,
3081 flags: FileQueryInfoFlags,
3082 io_priority: glib::Priority,
3083 ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileInfo, glib::Error>> + 'static>> {
3084 let attributes = String::from(attributes);
3085 Box_::pin(crate::GioFuture::new(
3086 self,
3087 move |obj, cancellable, send| {
3088 obj.query_info_async(
3089 &attributes,
3090 flags,
3091 io_priority,
3092 Some(cancellable),
3093 move |res| {
3094 send.resolve(res);
3095 },
3096 );
3097 },
3098 ))
3099 }
3100
3101 /// Obtain the list of settable attributes for the file.
3102 ///
3103 /// Returns the type and full attribute name of all the attributes
3104 /// that can be set on this file. This doesn't mean setting it will
3105 /// always succeed though, you might get an access failure, or some
3106 /// specific file may not support a specific attribute.
3107 ///
3108 /// If @cancellable is not [`None`], then the operation can be cancelled by
3109 /// triggering the cancellable object from another thread. If the operation
3110 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3111 /// ## `cancellable`
3112 /// optional #GCancellable object,
3113 /// [`None`] to ignore
3114 ///
3115 /// # Returns
3116 ///
3117 /// a #GFileAttributeInfoList describing the settable attributes.
3118 /// When you are done with it, release it with
3119 /// g_file_attribute_info_list_unref()
3120 #[doc(alias = "g_file_query_settable_attributes")]
3121 fn query_settable_attributes(
3122 &self,
3123 cancellable: Option<&impl IsA<Cancellable>>,
3124 ) -> Result<FileAttributeInfoList, glib::Error> {
3125 unsafe {
3126 let mut error = std::ptr::null_mut();
3127 let ret = ffi::g_file_query_settable_attributes(
3128 self.as_ref().to_glib_none().0,
3129 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3130 &mut error,
3131 );
3132 if error.is_null() {
3133 Ok(from_glib_full(ret))
3134 } else {
3135 Err(from_glib_full(error))
3136 }
3137 }
3138 }
3139
3140 /// Obtain the list of attribute namespaces where new attributes
3141 /// can be created by a user. An example of this is extended
3142 /// attributes (in the "xattr" namespace).
3143 ///
3144 /// If @cancellable is not [`None`], then the operation can be cancelled by
3145 /// triggering the cancellable object from another thread. If the operation
3146 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3147 /// ## `cancellable`
3148 /// optional #GCancellable object,
3149 /// [`None`] to ignore
3150 ///
3151 /// # Returns
3152 ///
3153 /// a #GFileAttributeInfoList describing the writable namespaces.
3154 /// When you are done with it, release it with
3155 /// g_file_attribute_info_list_unref()
3156 #[doc(alias = "g_file_query_writable_namespaces")]
3157 fn query_writable_namespaces(
3158 &self,
3159 cancellable: Option<&impl IsA<Cancellable>>,
3160 ) -> Result<FileAttributeInfoList, glib::Error> {
3161 unsafe {
3162 let mut error = std::ptr::null_mut();
3163 let ret = ffi::g_file_query_writable_namespaces(
3164 self.as_ref().to_glib_none().0,
3165 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3166 &mut error,
3167 );
3168 if error.is_null() {
3169 Ok(from_glib_full(ret))
3170 } else {
3171 Err(from_glib_full(error))
3172 }
3173 }
3174 }
3175
3176 /// Opens a file for reading. The result is a #GFileInputStream that
3177 /// can be used to read the contents of the file.
3178 ///
3179 /// If @cancellable is not [`None`], then the operation can be cancelled by
3180 /// triggering the cancellable object from another thread. If the operation
3181 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3182 ///
3183 /// If the file does not exist, the [`IOErrorEnum::NotFound`][crate::IOErrorEnum::NotFound] error will be
3184 /// returned. If the file is a directory, the [`IOErrorEnum::IsDirectory`][crate::IOErrorEnum::IsDirectory]
3185 /// error will be returned. Other errors are possible too, and depend
3186 /// on what kind of filesystem the file is on.
3187 /// ## `cancellable`
3188 /// a #GCancellable
3189 ///
3190 /// # Returns
3191 ///
3192 /// #GFileInputStream or [`None`] on error.
3193 /// Free the returned object with g_object_unref().
3194 #[doc(alias = "g_file_read")]
3195 fn read(
3196 &self,
3197 cancellable: Option<&impl IsA<Cancellable>>,
3198 ) -> Result<FileInputStream, glib::Error> {
3199 unsafe {
3200 let mut error = std::ptr::null_mut();
3201 let ret = ffi::g_file_read(
3202 self.as_ref().to_glib_none().0,
3203 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3204 &mut error,
3205 );
3206 if error.is_null() {
3207 Ok(from_glib_full(ret))
3208 } else {
3209 Err(from_glib_full(error))
3210 }
3211 }
3212 }
3213
3214 /// Asynchronously opens @self for reading.
3215 ///
3216 /// For more details, see g_file_read() which is
3217 /// the synchronous version of this call.
3218 ///
3219 /// When the operation is finished, @callback will be called.
3220 /// You can then call g_file_read_finish() to get the result
3221 /// of the operation.
3222 /// ## `io_priority`
3223 /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
3224 /// ## `cancellable`
3225 /// optional #GCancellable object,
3226 /// [`None`] to ignore
3227 /// ## `callback`
3228 /// a #GAsyncReadyCallback
3229 /// to call when the request is satisfied
3230 #[doc(alias = "g_file_read_async")]
3231 fn read_async<P: FnOnce(Result<FileInputStream, glib::Error>) + 'static>(
3232 &self,
3233 io_priority: glib::Priority,
3234 cancellable: Option<&impl IsA<Cancellable>>,
3235 callback: P,
3236 ) {
3237 let main_context = glib::MainContext::ref_thread_default();
3238 let is_main_context_owner = main_context.is_owner();
3239 let has_acquired_main_context = (!is_main_context_owner)
3240 .then(|| main_context.acquire().ok())
3241 .flatten();
3242 assert!(
3243 is_main_context_owner || has_acquired_main_context.is_some(),
3244 "Async operations only allowed if the thread is owning the MainContext"
3245 );
3246
3247 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
3248 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
3249 unsafe extern "C" fn read_async_trampoline<
3250 P: FnOnce(Result<FileInputStream, glib::Error>) + 'static,
3251 >(
3252 _source_object: *mut glib::gobject_ffi::GObject,
3253 res: *mut crate::ffi::GAsyncResult,
3254 user_data: glib::ffi::gpointer,
3255 ) {
3256 unsafe {
3257 let mut error = std::ptr::null_mut();
3258 let ret = ffi::g_file_read_finish(_source_object as *mut _, res, &mut error);
3259 let result = if error.is_null() {
3260 Ok(from_glib_full(ret))
3261 } else {
3262 Err(from_glib_full(error))
3263 };
3264 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
3265 Box_::from_raw(user_data as *mut _);
3266 let callback: P = callback.into_inner();
3267 callback(result);
3268 }
3269 }
3270 let callback = read_async_trampoline::<P>;
3271 unsafe {
3272 ffi::g_file_read_async(
3273 self.as_ref().to_glib_none().0,
3274 io_priority.into_glib(),
3275 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3276 Some(callback),
3277 Box_::into_raw(user_data) as *mut _,
3278 );
3279 }
3280 }
3281
3282 fn read_future(
3283 &self,
3284 io_priority: glib::Priority,
3285 ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileInputStream, glib::Error>> + 'static>>
3286 {
3287 Box_::pin(crate::GioFuture::new(
3288 self,
3289 move |obj, cancellable, send| {
3290 obj.read_async(io_priority, Some(cancellable), move |res| {
3291 send.resolve(res);
3292 });
3293 },
3294 ))
3295 }
3296
3297 /// Returns an output stream for overwriting the file, possibly
3298 /// creating a backup copy of the file first. If the file doesn't exist,
3299 /// it will be created.
3300 ///
3301 /// This will try to replace the file in the safest way possible so
3302 /// that any errors during the writing will not affect an already
3303 /// existing copy of the file. For instance, for local files it
3304 /// may write to a temporary file and then atomically rename over
3305 /// the destination when the stream is closed.
3306 ///
3307 /// By default files created are generally readable by everyone,
3308 /// but if you pass [`FileCreateFlags::PRIVATE`][crate::FileCreateFlags::PRIVATE] in @flags the file
3309 /// will be made readable only to the current user, to the level that
3310 /// is supported on the target filesystem.
3311 ///
3312 /// If @cancellable is not [`None`], then the operation can be cancelled
3313 /// by triggering the cancellable object from another thread. If the
3314 /// operation was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be
3315 /// returned.
3316 ///
3317 /// If you pass in a non-[`None`] @etag value and @self already exists, then
3318 /// this value is compared to the current entity tag of the file, and if
3319 /// they differ an [`IOErrorEnum::WrongEtag`][crate::IOErrorEnum::WrongEtag] error is returned. This
3320 /// generally means that the file has been changed since you last read
3321 /// it. You can get the new etag from g_file_output_stream_get_etag()
3322 /// after you've finished writing and closed the #GFileOutputStream. When
3323 /// you load a new file you can use g_file_input_stream_query_info() to
3324 /// get the etag of the file.
3325 ///
3326 /// If @make_backup is [`true`], this function will attempt to make a
3327 /// backup of the current file before overwriting it. If this fails
3328 /// a [`IOErrorEnum::CantCreateBackup`][crate::IOErrorEnum::CantCreateBackup] error will be returned. If you
3329 /// want to replace anyway, try again with @make_backup set to [`false`].
3330 ///
3331 /// If the file is a directory the [`IOErrorEnum::IsDirectory`][crate::IOErrorEnum::IsDirectory] error will
3332 /// be returned, and if the file is some other form of non-regular file
3333 /// then a [`IOErrorEnum::NotRegularFile`][crate::IOErrorEnum::NotRegularFile] error will be returned. Some
3334 /// file systems don't allow all file names, and may return an
3335 /// [`IOErrorEnum::InvalidFilename`][crate::IOErrorEnum::InvalidFilename] error, and if the name is to long
3336 /// [`IOErrorEnum::FilenameTooLong`][crate::IOErrorEnum::FilenameTooLong] will be returned. Other errors are
3337 /// possible too, and depend on what kind of filesystem the file is on.
3338 /// ## `etag`
3339 /// an optional [entity tag](#entity-tags)
3340 /// for the current #GFile, or #NULL to ignore
3341 /// ## `make_backup`
3342 /// [`true`] if a backup should be created
3343 /// ## `flags`
3344 /// a set of #GFileCreateFlags
3345 /// ## `cancellable`
3346 /// optional #GCancellable object,
3347 /// [`None`] to ignore
3348 ///
3349 /// # Returns
3350 ///
3351 /// a #GFileOutputStream or [`None`] on error.
3352 /// Free the returned object with g_object_unref().
3353 #[doc(alias = "g_file_replace")]
3354 fn replace(
3355 &self,
3356 etag: Option<&str>,
3357 make_backup: bool,
3358 flags: FileCreateFlags,
3359 cancellable: Option<&impl IsA<Cancellable>>,
3360 ) -> Result<FileOutputStream, glib::Error> {
3361 unsafe {
3362 let mut error = std::ptr::null_mut();
3363 let ret = ffi::g_file_replace(
3364 self.as_ref().to_glib_none().0,
3365 etag.to_glib_none().0,
3366 make_backup.into_glib(),
3367 flags.into_glib(),
3368 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3369 &mut error,
3370 );
3371 if error.is_null() {
3372 Ok(from_glib_full(ret))
3373 } else {
3374 Err(from_glib_full(error))
3375 }
3376 }
3377 }
3378
3379 /// Asynchronously overwrites the file, replacing the contents,
3380 /// possibly creating a backup copy of the file first.
3381 ///
3382 /// For more details, see g_file_replace() which is
3383 /// the synchronous version of this call.
3384 ///
3385 /// When the operation is finished, @callback will be called.
3386 /// You can then call g_file_replace_finish() to get the result
3387 /// of the operation.
3388 /// ## `etag`
3389 /// an [entity tag](#entity-tags) for the current #GFile,
3390 /// or [`None`] to ignore
3391 /// ## `make_backup`
3392 /// [`true`] if a backup should be created
3393 /// ## `flags`
3394 /// a set of #GFileCreateFlags
3395 /// ## `io_priority`
3396 /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
3397 /// ## `cancellable`
3398 /// optional #GCancellable object,
3399 /// [`None`] to ignore
3400 /// ## `callback`
3401 /// a #GAsyncReadyCallback
3402 /// to call when the request is satisfied
3403 #[doc(alias = "g_file_replace_async")]
3404 fn replace_async<P: FnOnce(Result<FileOutputStream, glib::Error>) + 'static>(
3405 &self,
3406 etag: Option<&str>,
3407 make_backup: bool,
3408 flags: FileCreateFlags,
3409 io_priority: glib::Priority,
3410 cancellable: Option<&impl IsA<Cancellable>>,
3411 callback: P,
3412 ) {
3413 let main_context = glib::MainContext::ref_thread_default();
3414 let is_main_context_owner = main_context.is_owner();
3415 let has_acquired_main_context = (!is_main_context_owner)
3416 .then(|| main_context.acquire().ok())
3417 .flatten();
3418 assert!(
3419 is_main_context_owner || has_acquired_main_context.is_some(),
3420 "Async operations only allowed if the thread is owning the MainContext"
3421 );
3422
3423 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
3424 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
3425 unsafe extern "C" fn replace_async_trampoline<
3426 P: FnOnce(Result<FileOutputStream, glib::Error>) + 'static,
3427 >(
3428 _source_object: *mut glib::gobject_ffi::GObject,
3429 res: *mut crate::ffi::GAsyncResult,
3430 user_data: glib::ffi::gpointer,
3431 ) {
3432 unsafe {
3433 let mut error = std::ptr::null_mut();
3434 let ret = ffi::g_file_replace_finish(_source_object as *mut _, res, &mut error);
3435 let result = if error.is_null() {
3436 Ok(from_glib_full(ret))
3437 } else {
3438 Err(from_glib_full(error))
3439 };
3440 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
3441 Box_::from_raw(user_data as *mut _);
3442 let callback: P = callback.into_inner();
3443 callback(result);
3444 }
3445 }
3446 let callback = replace_async_trampoline::<P>;
3447 unsafe {
3448 ffi::g_file_replace_async(
3449 self.as_ref().to_glib_none().0,
3450 etag.to_glib_none().0,
3451 make_backup.into_glib(),
3452 flags.into_glib(),
3453 io_priority.into_glib(),
3454 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3455 Some(callback),
3456 Box_::into_raw(user_data) as *mut _,
3457 );
3458 }
3459 }
3460
3461 fn replace_future(
3462 &self,
3463 etag: Option<&str>,
3464 make_backup: bool,
3465 flags: FileCreateFlags,
3466 io_priority: glib::Priority,
3467 ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileOutputStream, glib::Error>> + 'static>>
3468 {
3469 let etag = etag.map(ToOwned::to_owned);
3470 Box_::pin(crate::GioFuture::new(
3471 self,
3472 move |obj, cancellable, send| {
3473 obj.replace_async(
3474 etag.as_ref().map(::std::borrow::Borrow::borrow),
3475 make_backup,
3476 flags,
3477 io_priority,
3478 Some(cancellable),
3479 move |res| {
3480 send.resolve(res);
3481 },
3482 );
3483 },
3484 ))
3485 }
3486
3487 /// Replaces the contents of @self with @contents of @length bytes.
3488 ///
3489 /// If @etag is specified (not [`None`]), any existing file must have that etag,
3490 /// or the error [`IOErrorEnum::WrongEtag`][crate::IOErrorEnum::WrongEtag] will be returned.
3491 ///
3492 /// If @make_backup is [`true`], this function will attempt to make a backup
3493 /// of @self. Internally, it uses g_file_replace(), so will try to replace the
3494 /// file contents in the safest way possible. For example, atomic renames are
3495 /// used when replacing local files’ contents.
3496 ///
3497 /// If @cancellable is not [`None`], then the operation can be cancelled by
3498 /// triggering the cancellable object from another thread. If the operation
3499 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3500 ///
3501 /// The returned @new_etag can be used to verify that the file hasn't
3502 /// changed the next time it is saved over.
3503 /// ## `contents`
3504 /// a string containing the new contents for @self
3505 /// ## `etag`
3506 /// the old [entity-tag](#entity-tags) for the document,
3507 /// or [`None`]
3508 /// ## `make_backup`
3509 /// [`true`] if a backup should be created
3510 /// ## `flags`
3511 /// a set of #GFileCreateFlags
3512 /// ## `cancellable`
3513 /// optional #GCancellable object, [`None`] to ignore
3514 ///
3515 /// # Returns
3516 ///
3517 /// [`true`] if successful. If an error has occurred, this function
3518 /// will return [`false`] and set @error appropriately if present.
3519 ///
3520 /// ## `new_etag`
3521 /// a location to a new [entity tag](#entity-tags)
3522 /// for the document. This should be freed with g_free() when no longer
3523 /// needed, or [`None`]
3524 #[doc(alias = "g_file_replace_contents")]
3525 fn replace_contents(
3526 &self,
3527 contents: &[u8],
3528 etag: Option<&str>,
3529 make_backup: bool,
3530 flags: FileCreateFlags,
3531 cancellable: Option<&impl IsA<Cancellable>>,
3532 ) -> Result<Option<glib::GString>, glib::Error> {
3533 let length = contents.len() as _;
3534 unsafe {
3535 let mut new_etag = std::ptr::null_mut();
3536 let mut error = std::ptr::null_mut();
3537 let is_ok = ffi::g_file_replace_contents(
3538 self.as_ref().to_glib_none().0,
3539 contents.to_glib_none().0,
3540 length,
3541 etag.to_glib_none().0,
3542 make_backup.into_glib(),
3543 flags.into_glib(),
3544 &mut new_etag,
3545 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3546 &mut error,
3547 );
3548 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
3549 if error.is_null() {
3550 Ok(from_glib_full(new_etag))
3551 } else {
3552 Err(from_glib_full(error))
3553 }
3554 }
3555 }
3556
3557 /// Same as g_file_replace_contents_async() but takes a #GBytes input instead.
3558 /// This function will keep a ref on @contents until the operation is done.
3559 /// Unlike g_file_replace_contents_async() this allows forgetting about the
3560 /// content without waiting for the callback.
3561 ///
3562 /// When this operation has completed, @callback will be called with
3563 /// @user_user data, and the operation can be finalized with
3564 /// g_file_replace_contents_finish().
3565 /// ## `contents`
3566 /// a #GBytes
3567 /// ## `etag`
3568 /// a new [entity tag](#entity-tags) for the @self, or [`None`]
3569 /// ## `make_backup`
3570 /// [`true`] if a backup should be created
3571 /// ## `flags`
3572 /// a set of #GFileCreateFlags
3573 /// ## `cancellable`
3574 /// optional #GCancellable object, [`None`] to ignore
3575 /// ## `callback`
3576 /// a #GAsyncReadyCallback to call when the request is satisfied
3577 #[doc(alias = "g_file_replace_contents_bytes_async")]
3578 fn replace_contents_bytes_async<
3579 P: FnOnce(Result<Option<glib::GString>, glib::Error>) + 'static,
3580 >(
3581 &self,
3582 contents: &glib::Bytes,
3583 etag: Option<&str>,
3584 make_backup: bool,
3585 flags: FileCreateFlags,
3586 cancellable: Option<&impl IsA<Cancellable>>,
3587 callback: P,
3588 ) {
3589 let main_context = glib::MainContext::ref_thread_default();
3590 let is_main_context_owner = main_context.is_owner();
3591 let has_acquired_main_context = (!is_main_context_owner)
3592 .then(|| main_context.acquire().ok())
3593 .flatten();
3594 assert!(
3595 is_main_context_owner || has_acquired_main_context.is_some(),
3596 "Async operations only allowed if the thread is owning the MainContext"
3597 );
3598
3599 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
3600 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
3601 unsafe extern "C" fn replace_contents_bytes_async_trampoline<
3602 P: FnOnce(Result<Option<glib::GString>, glib::Error>) + 'static,
3603 >(
3604 _source_object: *mut glib::gobject_ffi::GObject,
3605 res: *mut crate::ffi::GAsyncResult,
3606 user_data: glib::ffi::gpointer,
3607 ) {
3608 unsafe {
3609 let mut error = std::ptr::null_mut();
3610 let mut new_etag = std::ptr::null_mut();
3611 ffi::g_file_replace_contents_finish(
3612 _source_object as *mut _,
3613 res,
3614 &mut new_etag,
3615 &mut error,
3616 );
3617 let result = if error.is_null() {
3618 Ok(from_glib_full(new_etag))
3619 } else {
3620 Err(from_glib_full(error))
3621 };
3622 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
3623 Box_::from_raw(user_data as *mut _);
3624 let callback: P = callback.into_inner();
3625 callback(result);
3626 }
3627 }
3628 let callback = replace_contents_bytes_async_trampoline::<P>;
3629 unsafe {
3630 ffi::g_file_replace_contents_bytes_async(
3631 self.as_ref().to_glib_none().0,
3632 contents.to_glib_none().0,
3633 etag.to_glib_none().0,
3634 make_backup.into_glib(),
3635 flags.into_glib(),
3636 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3637 Some(callback),
3638 Box_::into_raw(user_data) as *mut _,
3639 );
3640 }
3641 }
3642
3643 fn replace_contents_bytes_future(
3644 &self,
3645 contents: &glib::Bytes,
3646 etag: Option<&str>,
3647 make_backup: bool,
3648 flags: FileCreateFlags,
3649 ) -> Pin<
3650 Box_<
3651 dyn std::future::Future<Output = Result<Option<glib::GString>, glib::Error>> + 'static,
3652 >,
3653 > {
3654 let contents = contents.clone();
3655 let etag = etag.map(ToOwned::to_owned);
3656 Box_::pin(crate::GioFuture::new(
3657 self,
3658 move |obj, cancellable, send| {
3659 obj.replace_contents_bytes_async(
3660 &contents,
3661 etag.as_ref().map(::std::borrow::Borrow::borrow),
3662 make_backup,
3663 flags,
3664 Some(cancellable),
3665 move |res| {
3666 send.resolve(res);
3667 },
3668 );
3669 },
3670 ))
3671 }
3672
3673 /// Returns an output stream for overwriting the file in readwrite mode,
3674 /// possibly creating a backup copy of the file first. If the file doesn't
3675 /// exist, it will be created.
3676 ///
3677 /// For details about the behaviour, see g_file_replace() which does the
3678 /// same thing but returns an output stream only.
3679 ///
3680 /// Note that in many non-local file cases read and write streams are not
3681 /// supported, so make sure you really need to do read and write streaming,
3682 /// rather than just opening for reading or writing.
3683 /// ## `etag`
3684 /// an optional [entity tag](#entity-tags)
3685 /// for the current #GFile, or #NULL to ignore
3686 /// ## `make_backup`
3687 /// [`true`] if a backup should be created
3688 /// ## `flags`
3689 /// a set of #GFileCreateFlags
3690 /// ## `cancellable`
3691 /// optional #GCancellable object,
3692 /// [`None`] to ignore
3693 ///
3694 /// # Returns
3695 ///
3696 /// a #GFileIOStream or [`None`] on error.
3697 /// Free the returned object with g_object_unref().
3698 #[doc(alias = "g_file_replace_readwrite")]
3699 fn replace_readwrite(
3700 &self,
3701 etag: Option<&str>,
3702 make_backup: bool,
3703 flags: FileCreateFlags,
3704 cancellable: Option<&impl IsA<Cancellable>>,
3705 ) -> Result<FileIOStream, glib::Error> {
3706 unsafe {
3707 let mut error = std::ptr::null_mut();
3708 let ret = ffi::g_file_replace_readwrite(
3709 self.as_ref().to_glib_none().0,
3710 etag.to_glib_none().0,
3711 make_backup.into_glib(),
3712 flags.into_glib(),
3713 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3714 &mut error,
3715 );
3716 if error.is_null() {
3717 Ok(from_glib_full(ret))
3718 } else {
3719 Err(from_glib_full(error))
3720 }
3721 }
3722 }
3723
3724 /// Asynchronously overwrites the file in read-write mode,
3725 /// replacing the contents, possibly creating a backup copy
3726 /// of the file first.
3727 ///
3728 /// For more details, see g_file_replace_readwrite() which is
3729 /// the synchronous version of this call.
3730 ///
3731 /// When the operation is finished, @callback will be called.
3732 /// You can then call g_file_replace_readwrite_finish() to get
3733 /// the result of the operation.
3734 /// ## `etag`
3735 /// an [entity tag](#entity-tags) for the current #GFile,
3736 /// or [`None`] to ignore
3737 /// ## `make_backup`
3738 /// [`true`] if a backup should be created
3739 /// ## `flags`
3740 /// a set of #GFileCreateFlags
3741 /// ## `io_priority`
3742 /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
3743 /// ## `cancellable`
3744 /// optional #GCancellable object,
3745 /// [`None`] to ignore
3746 /// ## `callback`
3747 /// a #GAsyncReadyCallback
3748 /// to call when the request is satisfied
3749 #[doc(alias = "g_file_replace_readwrite_async")]
3750 fn replace_readwrite_async<P: FnOnce(Result<FileIOStream, glib::Error>) + 'static>(
3751 &self,
3752 etag: Option<&str>,
3753 make_backup: bool,
3754 flags: FileCreateFlags,
3755 io_priority: glib::Priority,
3756 cancellable: Option<&impl IsA<Cancellable>>,
3757 callback: P,
3758 ) {
3759 let main_context = glib::MainContext::ref_thread_default();
3760 let is_main_context_owner = main_context.is_owner();
3761 let has_acquired_main_context = (!is_main_context_owner)
3762 .then(|| main_context.acquire().ok())
3763 .flatten();
3764 assert!(
3765 is_main_context_owner || has_acquired_main_context.is_some(),
3766 "Async operations only allowed if the thread is owning the MainContext"
3767 );
3768
3769 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
3770 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
3771 unsafe extern "C" fn replace_readwrite_async_trampoline<
3772 P: FnOnce(Result<FileIOStream, glib::Error>) + 'static,
3773 >(
3774 _source_object: *mut glib::gobject_ffi::GObject,
3775 res: *mut crate::ffi::GAsyncResult,
3776 user_data: glib::ffi::gpointer,
3777 ) {
3778 unsafe {
3779 let mut error = std::ptr::null_mut();
3780 let ret =
3781 ffi::g_file_replace_readwrite_finish(_source_object as *mut _, res, &mut error);
3782 let result = if error.is_null() {
3783 Ok(from_glib_full(ret))
3784 } else {
3785 Err(from_glib_full(error))
3786 };
3787 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
3788 Box_::from_raw(user_data as *mut _);
3789 let callback: P = callback.into_inner();
3790 callback(result);
3791 }
3792 }
3793 let callback = replace_readwrite_async_trampoline::<P>;
3794 unsafe {
3795 ffi::g_file_replace_readwrite_async(
3796 self.as_ref().to_glib_none().0,
3797 etag.to_glib_none().0,
3798 make_backup.into_glib(),
3799 flags.into_glib(),
3800 io_priority.into_glib(),
3801 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3802 Some(callback),
3803 Box_::into_raw(user_data) as *mut _,
3804 );
3805 }
3806 }
3807
3808 fn replace_readwrite_future(
3809 &self,
3810 etag: Option<&str>,
3811 make_backup: bool,
3812 flags: FileCreateFlags,
3813 io_priority: glib::Priority,
3814 ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileIOStream, glib::Error>> + 'static>>
3815 {
3816 let etag = etag.map(ToOwned::to_owned);
3817 Box_::pin(crate::GioFuture::new(
3818 self,
3819 move |obj, cancellable, send| {
3820 obj.replace_readwrite_async(
3821 etag.as_ref().map(::std::borrow::Borrow::borrow),
3822 make_backup,
3823 flags,
3824 io_priority,
3825 Some(cancellable),
3826 move |res| {
3827 send.resolve(res);
3828 },
3829 );
3830 },
3831 ))
3832 }
3833
3834 /// Resolves a relative path for @self to an absolute path.
3835 ///
3836 /// This call does no blocking I/O.
3837 ///
3838 /// If the @relative_path is an absolute path name, the resolution
3839 /// is done absolutely (without taking @self path as base).
3840 /// ## `relative_path`
3841 /// a given relative path string
3842 ///
3843 /// # Returns
3844 ///
3845 /// a #GFile for the resolved path.
3846 #[doc(alias = "g_file_resolve_relative_path")]
3847 #[must_use]
3848 fn resolve_relative_path(&self, relative_path: impl AsRef<std::path::Path>) -> File {
3849 unsafe {
3850 from_glib_full(ffi::g_file_resolve_relative_path(
3851 self.as_ref().to_glib_none().0,
3852 relative_path.as_ref().to_glib_none().0,
3853 ))
3854 }
3855 }
3856
3857 //#[doc(alias = "g_file_set_attribute")]
3858 //fn set_attribute(&self, attribute: &str, type_: FileAttributeType, value_p: /*Unimplemented*/Option<Basic: Pointer>, flags: FileQueryInfoFlags, cancellable: Option<&impl IsA<Cancellable>>) -> Result<(), glib::Error> {
3859 // unsafe { TODO: call ffi:g_file_set_attribute() }
3860 //}
3861
3862 /// Sets @attribute of type [`FileAttributeType::ByteString`][crate::FileAttributeType::ByteString] to @value.
3863 /// If @attribute is of a different type, this operation will fail,
3864 /// returning [`false`].
3865 ///
3866 /// If @cancellable is not [`None`], then the operation can be cancelled by
3867 /// triggering the cancellable object from another thread. If the operation
3868 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3869 /// ## `attribute`
3870 /// a string containing the attribute's name
3871 /// ## `value`
3872 /// a string containing the attribute's new value
3873 /// ## `flags`
3874 /// a #GFileQueryInfoFlags
3875 /// ## `cancellable`
3876 /// optional #GCancellable object,
3877 /// [`None`] to ignore
3878 ///
3879 /// # Returns
3880 ///
3881 /// [`true`] if the @attribute was successfully set to @value
3882 /// in the @self, [`false`] otherwise.
3883 #[doc(alias = "g_file_set_attribute_byte_string")]
3884 fn set_attribute_byte_string(
3885 &self,
3886 attribute: &str,
3887 value: &str,
3888 flags: FileQueryInfoFlags,
3889 cancellable: Option<&impl IsA<Cancellable>>,
3890 ) -> Result<(), glib::Error> {
3891 unsafe {
3892 let mut error = std::ptr::null_mut();
3893 let is_ok = ffi::g_file_set_attribute_byte_string(
3894 self.as_ref().to_glib_none().0,
3895 attribute.to_glib_none().0,
3896 value.to_glib_none().0,
3897 flags.into_glib(),
3898 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3899 &mut error,
3900 );
3901 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
3902 if error.is_null() {
3903 Ok(())
3904 } else {
3905 Err(from_glib_full(error))
3906 }
3907 }
3908 }
3909
3910 /// Sets @attribute of type [`FileAttributeType::Int32`][crate::FileAttributeType::Int32] to @value.
3911 /// If @attribute is of a different type, this operation will fail.
3912 ///
3913 /// If @cancellable is not [`None`], then the operation can be cancelled by
3914 /// triggering the cancellable object from another thread. If the operation
3915 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3916 /// ## `attribute`
3917 /// a string containing the attribute's name
3918 /// ## `value`
3919 /// a #gint32 containing the attribute's new value
3920 /// ## `flags`
3921 /// a #GFileQueryInfoFlags
3922 /// ## `cancellable`
3923 /// optional #GCancellable object,
3924 /// [`None`] to ignore
3925 ///
3926 /// # Returns
3927 ///
3928 /// [`true`] if the @attribute was successfully set to @value
3929 /// in the @self, [`false`] otherwise.
3930 #[doc(alias = "g_file_set_attribute_int32")]
3931 fn set_attribute_int32(
3932 &self,
3933 attribute: &str,
3934 value: i32,
3935 flags: FileQueryInfoFlags,
3936 cancellable: Option<&impl IsA<Cancellable>>,
3937 ) -> Result<(), glib::Error> {
3938 unsafe {
3939 let mut error = std::ptr::null_mut();
3940 let is_ok = ffi::g_file_set_attribute_int32(
3941 self.as_ref().to_glib_none().0,
3942 attribute.to_glib_none().0,
3943 value,
3944 flags.into_glib(),
3945 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3946 &mut error,
3947 );
3948 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
3949 if error.is_null() {
3950 Ok(())
3951 } else {
3952 Err(from_glib_full(error))
3953 }
3954 }
3955 }
3956
3957 /// Sets @attribute of type [`FileAttributeType::Int64`][crate::FileAttributeType::Int64] to @value.
3958 /// If @attribute is of a different type, this operation will fail.
3959 ///
3960 /// If @cancellable is not [`None`], then the operation can be cancelled by
3961 /// triggering the cancellable object from another thread. If the operation
3962 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3963 /// ## `attribute`
3964 /// a string containing the attribute's name
3965 /// ## `value`
3966 /// a #guint64 containing the attribute's new value
3967 /// ## `flags`
3968 /// a #GFileQueryInfoFlags
3969 /// ## `cancellable`
3970 /// optional #GCancellable object,
3971 /// [`None`] to ignore
3972 ///
3973 /// # Returns
3974 ///
3975 /// [`true`] if the @attribute was successfully set, [`false`] otherwise.
3976 #[doc(alias = "g_file_set_attribute_int64")]
3977 fn set_attribute_int64(
3978 &self,
3979 attribute: &str,
3980 value: i64,
3981 flags: FileQueryInfoFlags,
3982 cancellable: Option<&impl IsA<Cancellable>>,
3983 ) -> Result<(), glib::Error> {
3984 unsafe {
3985 let mut error = std::ptr::null_mut();
3986 let is_ok = ffi::g_file_set_attribute_int64(
3987 self.as_ref().to_glib_none().0,
3988 attribute.to_glib_none().0,
3989 value,
3990 flags.into_glib(),
3991 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3992 &mut error,
3993 );
3994 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
3995 if error.is_null() {
3996 Ok(())
3997 } else {
3998 Err(from_glib_full(error))
3999 }
4000 }
4001 }
4002
4003 /// Sets @attribute of type [`FileAttributeType::String`][crate::FileAttributeType::String] to @value.
4004 /// If @attribute is of a different type, this operation will fail.
4005 ///
4006 /// If @cancellable is not [`None`], then the operation can be cancelled by
4007 /// triggering the cancellable object from another thread. If the operation
4008 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4009 /// ## `attribute`
4010 /// a string containing the attribute's name
4011 /// ## `value`
4012 /// a string containing the attribute's value
4013 /// ## `flags`
4014 /// #GFileQueryInfoFlags
4015 /// ## `cancellable`
4016 /// optional #GCancellable object,
4017 /// [`None`] to ignore
4018 ///
4019 /// # Returns
4020 ///
4021 /// [`true`] if the @attribute was successfully set, [`false`] otherwise.
4022 #[doc(alias = "g_file_set_attribute_string")]
4023 fn set_attribute_string(
4024 &self,
4025 attribute: &str,
4026 value: &str,
4027 flags: FileQueryInfoFlags,
4028 cancellable: Option<&impl IsA<Cancellable>>,
4029 ) -> Result<(), glib::Error> {
4030 unsafe {
4031 let mut error = std::ptr::null_mut();
4032 let is_ok = ffi::g_file_set_attribute_string(
4033 self.as_ref().to_glib_none().0,
4034 attribute.to_glib_none().0,
4035 value.to_glib_none().0,
4036 flags.into_glib(),
4037 cancellable.map(|p| p.as_ref()).to_glib_none().0,
4038 &mut error,
4039 );
4040 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
4041 if error.is_null() {
4042 Ok(())
4043 } else {
4044 Err(from_glib_full(error))
4045 }
4046 }
4047 }
4048
4049 /// Sets @attribute of type [`FileAttributeType::Uint32`][crate::FileAttributeType::Uint32] to @value.
4050 /// If @attribute is of a different type, this operation will fail.
4051 ///
4052 /// If @cancellable is not [`None`], then the operation can be cancelled by
4053 /// triggering the cancellable object from another thread. If the operation
4054 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4055 /// ## `attribute`
4056 /// a string containing the attribute's name
4057 /// ## `value`
4058 /// a #guint32 containing the attribute's new value
4059 /// ## `flags`
4060 /// a #GFileQueryInfoFlags
4061 /// ## `cancellable`
4062 /// optional #GCancellable object,
4063 /// [`None`] to ignore
4064 ///
4065 /// # Returns
4066 ///
4067 /// [`true`] if the @attribute was successfully set to @value
4068 /// in the @self, [`false`] otherwise.
4069 #[doc(alias = "g_file_set_attribute_uint32")]
4070 fn set_attribute_uint32(
4071 &self,
4072 attribute: &str,
4073 value: u32,
4074 flags: FileQueryInfoFlags,
4075 cancellable: Option<&impl IsA<Cancellable>>,
4076 ) -> Result<(), glib::Error> {
4077 unsafe {
4078 let mut error = std::ptr::null_mut();
4079 let is_ok = ffi::g_file_set_attribute_uint32(
4080 self.as_ref().to_glib_none().0,
4081 attribute.to_glib_none().0,
4082 value,
4083 flags.into_glib(),
4084 cancellable.map(|p| p.as_ref()).to_glib_none().0,
4085 &mut error,
4086 );
4087 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
4088 if error.is_null() {
4089 Ok(())
4090 } else {
4091 Err(from_glib_full(error))
4092 }
4093 }
4094 }
4095
4096 /// Sets @attribute of type [`FileAttributeType::Uint64`][crate::FileAttributeType::Uint64] to @value.
4097 /// If @attribute is of a different type, this operation will fail.
4098 ///
4099 /// If @cancellable is not [`None`], then the operation can be cancelled by
4100 /// triggering the cancellable object from another thread. If the operation
4101 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4102 /// ## `attribute`
4103 /// a string containing the attribute's name
4104 /// ## `value`
4105 /// a #guint64 containing the attribute's new value
4106 /// ## `flags`
4107 /// a #GFileQueryInfoFlags
4108 /// ## `cancellable`
4109 /// optional #GCancellable object,
4110 /// [`None`] to ignore
4111 ///
4112 /// # Returns
4113 ///
4114 /// [`true`] if the @attribute was successfully set to @value
4115 /// in the @self, [`false`] otherwise.
4116 #[doc(alias = "g_file_set_attribute_uint64")]
4117 fn set_attribute_uint64(
4118 &self,
4119 attribute: &str,
4120 value: u64,
4121 flags: FileQueryInfoFlags,
4122 cancellable: Option<&impl IsA<Cancellable>>,
4123 ) -> Result<(), glib::Error> {
4124 unsafe {
4125 let mut error = std::ptr::null_mut();
4126 let is_ok = ffi::g_file_set_attribute_uint64(
4127 self.as_ref().to_glib_none().0,
4128 attribute.to_glib_none().0,
4129 value,
4130 flags.into_glib(),
4131 cancellable.map(|p| p.as_ref()).to_glib_none().0,
4132 &mut error,
4133 );
4134 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
4135 if error.is_null() {
4136 Ok(())
4137 } else {
4138 Err(from_glib_full(error))
4139 }
4140 }
4141 }
4142
4143 /// Asynchronously sets the attributes of @self with @info.
4144 ///
4145 /// For more details, see g_file_set_attributes_from_info(),
4146 /// which is the synchronous version of this call.
4147 ///
4148 /// When the operation is finished, @callback will be called.
4149 /// You can then call g_file_set_attributes_finish() to get
4150 /// the result of the operation.
4151 /// ## `info`
4152 /// a #GFileInfo
4153 /// ## `flags`
4154 /// a #GFileQueryInfoFlags
4155 /// ## `io_priority`
4156 /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
4157 /// ## `cancellable`
4158 /// optional #GCancellable object,
4159 /// [`None`] to ignore
4160 /// ## `callback`
4161 /// a #GAsyncReadyCallback
4162 /// to call when the request is satisfied
4163 #[doc(alias = "g_file_set_attributes_async")]
4164 fn set_attributes_async<P: FnOnce(Result<FileInfo, glib::Error>) + 'static>(
4165 &self,
4166 info: &FileInfo,
4167 flags: FileQueryInfoFlags,
4168 io_priority: glib::Priority,
4169 cancellable: Option<&impl IsA<Cancellable>>,
4170 callback: P,
4171 ) {
4172 let main_context = glib::MainContext::ref_thread_default();
4173 let is_main_context_owner = main_context.is_owner();
4174 let has_acquired_main_context = (!is_main_context_owner)
4175 .then(|| main_context.acquire().ok())
4176 .flatten();
4177 assert!(
4178 is_main_context_owner || has_acquired_main_context.is_some(),
4179 "Async operations only allowed if the thread is owning the MainContext"
4180 );
4181
4182 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
4183 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
4184 unsafe extern "C" fn set_attributes_async_trampoline<
4185 P: FnOnce(Result<FileInfo, glib::Error>) + 'static,
4186 >(
4187 _source_object: *mut glib::gobject_ffi::GObject,
4188 res: *mut crate::ffi::GAsyncResult,
4189 user_data: glib::ffi::gpointer,
4190 ) {
4191 unsafe {
4192 let mut error = std::ptr::null_mut();
4193 let mut info = std::ptr::null_mut();
4194 ffi::g_file_set_attributes_finish(
4195 _source_object as *mut _,
4196 res,
4197 &mut info,
4198 &mut error,
4199 );
4200 let result = if error.is_null() {
4201 Ok(from_glib_full(info))
4202 } else {
4203 Err(from_glib_full(error))
4204 };
4205 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
4206 Box_::from_raw(user_data as *mut _);
4207 let callback: P = callback.into_inner();
4208 callback(result);
4209 }
4210 }
4211 let callback = set_attributes_async_trampoline::<P>;
4212 unsafe {
4213 ffi::g_file_set_attributes_async(
4214 self.as_ref().to_glib_none().0,
4215 info.to_glib_none().0,
4216 flags.into_glib(),
4217 io_priority.into_glib(),
4218 cancellable.map(|p| p.as_ref()).to_glib_none().0,
4219 Some(callback),
4220 Box_::into_raw(user_data) as *mut _,
4221 );
4222 }
4223 }
4224
4225 fn set_attributes_future(
4226 &self,
4227 info: &FileInfo,
4228 flags: FileQueryInfoFlags,
4229 io_priority: glib::Priority,
4230 ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileInfo, glib::Error>> + 'static>> {
4231 let info = info.clone();
4232 Box_::pin(crate::GioFuture::new(
4233 self,
4234 move |obj, cancellable, send| {
4235 obj.set_attributes_async(
4236 &info,
4237 flags,
4238 io_priority,
4239 Some(cancellable),
4240 move |res| {
4241 send.resolve(res);
4242 },
4243 );
4244 },
4245 ))
4246 }
4247
4248 /// Tries to set all attributes in the #GFileInfo on the target
4249 /// values, not stopping on the first error.
4250 ///
4251 /// If there is any error during this operation then @error will
4252 /// be set to the first error. Error on particular fields are flagged
4253 /// by setting the "status" field in the attribute value to
4254 /// [`FileAttributeStatus::ErrorSetting`][crate::FileAttributeStatus::ErrorSetting], which means you can
4255 /// also detect further errors.
4256 ///
4257 /// If @cancellable is not [`None`], then the operation can be cancelled by
4258 /// triggering the cancellable object from another thread. If the operation
4259 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4260 /// ## `info`
4261 /// a #GFileInfo
4262 /// ## `flags`
4263 /// #GFileQueryInfoFlags
4264 /// ## `cancellable`
4265 /// optional #GCancellable object,
4266 /// [`None`] to ignore
4267 ///
4268 /// # Returns
4269 ///
4270 /// [`false`] if there was any error, [`true`] otherwise.
4271 #[doc(alias = "g_file_set_attributes_from_info")]
4272 fn set_attributes_from_info(
4273 &self,
4274 info: &FileInfo,
4275 flags: FileQueryInfoFlags,
4276 cancellable: Option<&impl IsA<Cancellable>>,
4277 ) -> Result<(), glib::Error> {
4278 unsafe {
4279 let mut error = std::ptr::null_mut();
4280 let is_ok = ffi::g_file_set_attributes_from_info(
4281 self.as_ref().to_glib_none().0,
4282 info.to_glib_none().0,
4283 flags.into_glib(),
4284 cancellable.map(|p| p.as_ref()).to_glib_none().0,
4285 &mut error,
4286 );
4287 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
4288 if error.is_null() {
4289 Ok(())
4290 } else {
4291 Err(from_glib_full(error))
4292 }
4293 }
4294 }
4295
4296 /// Renames @self to the specified display name.
4297 ///
4298 /// The display name is converted from UTF-8 to the correct encoding
4299 /// for the target filesystem if possible and the @self is renamed to this.
4300 ///
4301 /// If you want to implement a rename operation in the user interface the
4302 /// edit name ([`FILE_ATTRIBUTE_STANDARD_EDIT_NAME`][crate::FILE_ATTRIBUTE_STANDARD_EDIT_NAME]) should be used as the
4303 /// initial value in the rename widget, and then the result after editing
4304 /// should be passed to g_file_set_display_name().
4305 ///
4306 /// On success the resulting converted filename is returned.
4307 ///
4308 /// If @cancellable is not [`None`], then the operation can be cancelled by
4309 /// triggering the cancellable object from another thread. If the operation
4310 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4311 /// ## `display_name`
4312 /// a string
4313 /// ## `cancellable`
4314 /// optional #GCancellable object,
4315 /// [`None`] to ignore
4316 ///
4317 /// # Returns
4318 ///
4319 /// a #GFile specifying what @self was renamed to,
4320 /// or [`None`] if there was an error.
4321 /// Free the returned object with g_object_unref().
4322 #[doc(alias = "g_file_set_display_name")]
4323 fn set_display_name(
4324 &self,
4325 display_name: &str,
4326 cancellable: Option<&impl IsA<Cancellable>>,
4327 ) -> Result<File, glib::Error> {
4328 unsafe {
4329 let mut error = std::ptr::null_mut();
4330 let ret = ffi::g_file_set_display_name(
4331 self.as_ref().to_glib_none().0,
4332 display_name.to_glib_none().0,
4333 cancellable.map(|p| p.as_ref()).to_glib_none().0,
4334 &mut error,
4335 );
4336 if error.is_null() {
4337 Ok(from_glib_full(ret))
4338 } else {
4339 Err(from_glib_full(error))
4340 }
4341 }
4342 }
4343
4344 /// Asynchronously sets the display name for a given #GFile.
4345 ///
4346 /// For more details, see g_file_set_display_name() which is
4347 /// the synchronous version of this call.
4348 ///
4349 /// When the operation is finished, @callback will be called.
4350 /// You can then call g_file_set_display_name_finish() to get
4351 /// the result of the operation.
4352 /// ## `display_name`
4353 /// a string
4354 /// ## `io_priority`
4355 /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
4356 /// ## `cancellable`
4357 /// optional #GCancellable object,
4358 /// [`None`] to ignore
4359 /// ## `callback`
4360 /// a #GAsyncReadyCallback
4361 /// to call when the request is satisfied
4362 #[doc(alias = "g_file_set_display_name_async")]
4363 fn set_display_name_async<P: FnOnce(Result<File, glib::Error>) + 'static>(
4364 &self,
4365 display_name: &str,
4366 io_priority: glib::Priority,
4367 cancellable: Option<&impl IsA<Cancellable>>,
4368 callback: P,
4369 ) {
4370 let main_context = glib::MainContext::ref_thread_default();
4371 let is_main_context_owner = main_context.is_owner();
4372 let has_acquired_main_context = (!is_main_context_owner)
4373 .then(|| main_context.acquire().ok())
4374 .flatten();
4375 assert!(
4376 is_main_context_owner || has_acquired_main_context.is_some(),
4377 "Async operations only allowed if the thread is owning the MainContext"
4378 );
4379
4380 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
4381 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
4382 unsafe extern "C" fn set_display_name_async_trampoline<
4383 P: FnOnce(Result<File, glib::Error>) + 'static,
4384 >(
4385 _source_object: *mut glib::gobject_ffi::GObject,
4386 res: *mut crate::ffi::GAsyncResult,
4387 user_data: glib::ffi::gpointer,
4388 ) {
4389 unsafe {
4390 let mut error = std::ptr::null_mut();
4391 let ret =
4392 ffi::g_file_set_display_name_finish(_source_object as *mut _, res, &mut error);
4393 let result = if error.is_null() {
4394 Ok(from_glib_full(ret))
4395 } else {
4396 Err(from_glib_full(error))
4397 };
4398 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
4399 Box_::from_raw(user_data as *mut _);
4400 let callback: P = callback.into_inner();
4401 callback(result);
4402 }
4403 }
4404 let callback = set_display_name_async_trampoline::<P>;
4405 unsafe {
4406 ffi::g_file_set_display_name_async(
4407 self.as_ref().to_glib_none().0,
4408 display_name.to_glib_none().0,
4409 io_priority.into_glib(),
4410 cancellable.map(|p| p.as_ref()).to_glib_none().0,
4411 Some(callback),
4412 Box_::into_raw(user_data) as *mut _,
4413 );
4414 }
4415 }
4416
4417 fn set_display_name_future(
4418 &self,
4419 display_name: &str,
4420 io_priority: glib::Priority,
4421 ) -> Pin<Box_<dyn std::future::Future<Output = Result<File, glib::Error>> + 'static>> {
4422 let display_name = String::from(display_name);
4423 Box_::pin(crate::GioFuture::new(
4424 self,
4425 move |obj, cancellable, send| {
4426 obj.set_display_name_async(
4427 &display_name,
4428 io_priority,
4429 Some(cancellable),
4430 move |res| {
4431 send.resolve(res);
4432 },
4433 );
4434 },
4435 ))
4436 }
4437
4438 /// Starts a file of type [`FileType::Mountable`][crate::FileType::Mountable].
4439 /// Using @start_operation, you can request callbacks when, for instance,
4440 /// passwords are needed during authentication.
4441 ///
4442 /// If @cancellable is not [`None`], then the operation can be cancelled by
4443 /// triggering the cancellable object from another thread. If the operation
4444 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4445 ///
4446 /// When the operation is finished, @callback will be called.
4447 /// You can then call g_file_mount_mountable_finish() to get
4448 /// the result of the operation.
4449 /// ## `flags`
4450 /// flags affecting the operation
4451 /// ## `start_operation`
4452 /// a #GMountOperation, or [`None`] to avoid user interaction
4453 /// ## `cancellable`
4454 /// optional #GCancellable object, [`None`] to ignore
4455 /// ## `callback`
4456 /// a #GAsyncReadyCallback to call when the request is satisfied, or [`None`]
4457 #[doc(alias = "g_file_start_mountable")]
4458 fn start_mountable<P: FnOnce(Result<(), glib::Error>) + 'static>(
4459 &self,
4460 flags: DriveStartFlags,
4461 start_operation: Option<&impl IsA<MountOperation>>,
4462 cancellable: Option<&impl IsA<Cancellable>>,
4463 callback: P,
4464 ) {
4465 let main_context = glib::MainContext::ref_thread_default();
4466 let is_main_context_owner = main_context.is_owner();
4467 let has_acquired_main_context = (!is_main_context_owner)
4468 .then(|| main_context.acquire().ok())
4469 .flatten();
4470 assert!(
4471 is_main_context_owner || has_acquired_main_context.is_some(),
4472 "Async operations only allowed if the thread is owning the MainContext"
4473 );
4474
4475 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
4476 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
4477 unsafe extern "C" fn start_mountable_trampoline<
4478 P: FnOnce(Result<(), glib::Error>) + 'static,
4479 >(
4480 _source_object: *mut glib::gobject_ffi::GObject,
4481 res: *mut crate::ffi::GAsyncResult,
4482 user_data: glib::ffi::gpointer,
4483 ) {
4484 unsafe {
4485 let mut error = std::ptr::null_mut();
4486 ffi::g_file_start_mountable_finish(_source_object as *mut _, res, &mut error);
4487 let result = if error.is_null() {
4488 Ok(())
4489 } else {
4490 Err(from_glib_full(error))
4491 };
4492 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
4493 Box_::from_raw(user_data as *mut _);
4494 let callback: P = callback.into_inner();
4495 callback(result);
4496 }
4497 }
4498 let callback = start_mountable_trampoline::<P>;
4499 unsafe {
4500 ffi::g_file_start_mountable(
4501 self.as_ref().to_glib_none().0,
4502 flags.into_glib(),
4503 start_operation.map(|p| p.as_ref()).to_glib_none().0,
4504 cancellable.map(|p| p.as_ref()).to_glib_none().0,
4505 Some(callback),
4506 Box_::into_raw(user_data) as *mut _,
4507 );
4508 }
4509 }
4510
4511 fn start_mountable_future(
4512 &self,
4513 flags: DriveStartFlags,
4514 start_operation: Option<&(impl IsA<MountOperation> + Clone + 'static)>,
4515 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
4516 let start_operation = start_operation.map(ToOwned::to_owned);
4517 Box_::pin(crate::GioFuture::new(
4518 self,
4519 move |obj, cancellable, send| {
4520 obj.start_mountable(
4521 flags,
4522 start_operation.as_ref().map(::std::borrow::Borrow::borrow),
4523 Some(cancellable),
4524 move |res| {
4525 send.resolve(res);
4526 },
4527 );
4528 },
4529 ))
4530 }
4531
4532 /// Stops a file of type [`FileType::Mountable`][crate::FileType::Mountable].
4533 ///
4534 /// If @cancellable is not [`None`], then the operation can be cancelled by
4535 /// triggering the cancellable object from another thread. If the operation
4536 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4537 ///
4538 /// When the operation is finished, @callback will be called.
4539 /// You can then call g_file_stop_mountable_finish() to get
4540 /// the result of the operation.
4541 /// ## `flags`
4542 /// flags affecting the operation
4543 /// ## `mount_operation`
4544 /// a #GMountOperation,
4545 /// or [`None`] to avoid user interaction.
4546 /// ## `cancellable`
4547 /// optional #GCancellable object,
4548 /// [`None`] to ignore
4549 /// ## `callback`
4550 /// a #GAsyncReadyCallback to call
4551 /// when the request is satisfied, or [`None`]
4552 #[doc(alias = "g_file_stop_mountable")]
4553 fn stop_mountable<P: FnOnce(Result<(), glib::Error>) + 'static>(
4554 &self,
4555 flags: MountUnmountFlags,
4556 mount_operation: Option<&impl IsA<MountOperation>>,
4557 cancellable: Option<&impl IsA<Cancellable>>,
4558 callback: P,
4559 ) {
4560 let main_context = glib::MainContext::ref_thread_default();
4561 let is_main_context_owner = main_context.is_owner();
4562 let has_acquired_main_context = (!is_main_context_owner)
4563 .then(|| main_context.acquire().ok())
4564 .flatten();
4565 assert!(
4566 is_main_context_owner || has_acquired_main_context.is_some(),
4567 "Async operations only allowed if the thread is owning the MainContext"
4568 );
4569
4570 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
4571 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
4572 unsafe extern "C" fn stop_mountable_trampoline<
4573 P: FnOnce(Result<(), glib::Error>) + 'static,
4574 >(
4575 _source_object: *mut glib::gobject_ffi::GObject,
4576 res: *mut crate::ffi::GAsyncResult,
4577 user_data: glib::ffi::gpointer,
4578 ) {
4579 unsafe {
4580 let mut error = std::ptr::null_mut();
4581 ffi::g_file_stop_mountable_finish(_source_object as *mut _, res, &mut error);
4582 let result = if error.is_null() {
4583 Ok(())
4584 } else {
4585 Err(from_glib_full(error))
4586 };
4587 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
4588 Box_::from_raw(user_data as *mut _);
4589 let callback: P = callback.into_inner();
4590 callback(result);
4591 }
4592 }
4593 let callback = stop_mountable_trampoline::<P>;
4594 unsafe {
4595 ffi::g_file_stop_mountable(
4596 self.as_ref().to_glib_none().0,
4597 flags.into_glib(),
4598 mount_operation.map(|p| p.as_ref()).to_glib_none().0,
4599 cancellable.map(|p| p.as_ref()).to_glib_none().0,
4600 Some(callback),
4601 Box_::into_raw(user_data) as *mut _,
4602 );
4603 }
4604 }
4605
4606 fn stop_mountable_future(
4607 &self,
4608 flags: MountUnmountFlags,
4609 mount_operation: Option<&(impl IsA<MountOperation> + Clone + 'static)>,
4610 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
4611 let mount_operation = mount_operation.map(ToOwned::to_owned);
4612 Box_::pin(crate::GioFuture::new(
4613 self,
4614 move |obj, cancellable, send| {
4615 obj.stop_mountable(
4616 flags,
4617 mount_operation.as_ref().map(::std::borrow::Borrow::borrow),
4618 Some(cancellable),
4619 move |res| {
4620 send.resolve(res);
4621 },
4622 );
4623 },
4624 ))
4625 }
4626
4627 /// Checks if @self supports thread-default main contexts
4628 /// (see [`glib::MainContext::push_thread_default()`][crate::glib::MainContext::push_thread_default()])
4629 /// If this returns [`false`], you cannot perform asynchronous operations on
4630 /// @self in a thread that has a thread-default context.
4631 ///
4632 /// # Returns
4633 ///
4634 /// Whether or not @self supports thread-default contexts.
4635 #[doc(alias = "g_file_supports_thread_contexts")]
4636 fn supports_thread_contexts(&self) -> bool {
4637 unsafe {
4638 from_glib(ffi::g_file_supports_thread_contexts(
4639 self.as_ref().to_glib_none().0,
4640 ))
4641 }
4642 }
4643
4644 /// Sends @self to the "Trashcan", if possible. This is similar to
4645 /// deleting it, but the user can recover it before emptying the trashcan.
4646 /// Trashing is disabled for system mounts by default (see
4647 /// g_unix_mount_entry_is_system_internal()), so this call can return the
4648 /// [`IOErrorEnum::NotSupported`][crate::IOErrorEnum::NotSupported] error. Since GLib 2.66, the `x-gvfs-notrash` unix
4649 /// mount option can be used to disable g_file_trash() support for particular
4650 /// mounts, the [`IOErrorEnum::NotSupported`][crate::IOErrorEnum::NotSupported] error will be returned in that case.
4651 /// Since 2.82, the `x-gvfs-trash` unix mount option can be used to enable
4652 /// g_file_trash() support for particular system mounts.
4653 ///
4654 /// If @cancellable is not [`None`], then the operation can be cancelled by
4655 /// triggering the cancellable object from another thread. If the operation
4656 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4657 /// ## `cancellable`
4658 /// optional #GCancellable object,
4659 /// [`None`] to ignore
4660 ///
4661 /// # Returns
4662 ///
4663 /// [`true`] on successful trash, [`false`] otherwise.
4664 #[doc(alias = "g_file_trash")]
4665 fn trash(&self, cancellable: Option<&impl IsA<Cancellable>>) -> Result<(), glib::Error> {
4666 unsafe {
4667 let mut error = std::ptr::null_mut();
4668 let is_ok = ffi::g_file_trash(
4669 self.as_ref().to_glib_none().0,
4670 cancellable.map(|p| p.as_ref()).to_glib_none().0,
4671 &mut error,
4672 );
4673 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
4674 if error.is_null() {
4675 Ok(())
4676 } else {
4677 Err(from_glib_full(error))
4678 }
4679 }
4680 }
4681
4682 /// Asynchronously sends @self to the Trash location, if possible.
4683 /// ## `io_priority`
4684 /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
4685 /// ## `cancellable`
4686 /// optional #GCancellable object,
4687 /// [`None`] to ignore
4688 /// ## `callback`
4689 /// a #GAsyncReadyCallback to call
4690 /// when the request is satisfied
4691 #[doc(alias = "g_file_trash_async")]
4692 fn trash_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
4693 &self,
4694 io_priority: glib::Priority,
4695 cancellable: Option<&impl IsA<Cancellable>>,
4696 callback: P,
4697 ) {
4698 let main_context = glib::MainContext::ref_thread_default();
4699 let is_main_context_owner = main_context.is_owner();
4700 let has_acquired_main_context = (!is_main_context_owner)
4701 .then(|| main_context.acquire().ok())
4702 .flatten();
4703 assert!(
4704 is_main_context_owner || has_acquired_main_context.is_some(),
4705 "Async operations only allowed if the thread is owning the MainContext"
4706 );
4707
4708 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
4709 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
4710 unsafe extern "C" fn trash_async_trampoline<
4711 P: FnOnce(Result<(), glib::Error>) + 'static,
4712 >(
4713 _source_object: *mut glib::gobject_ffi::GObject,
4714 res: *mut crate::ffi::GAsyncResult,
4715 user_data: glib::ffi::gpointer,
4716 ) {
4717 unsafe {
4718 let mut error = std::ptr::null_mut();
4719 ffi::g_file_trash_finish(_source_object as *mut _, res, &mut error);
4720 let result = if error.is_null() {
4721 Ok(())
4722 } else {
4723 Err(from_glib_full(error))
4724 };
4725 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
4726 Box_::from_raw(user_data as *mut _);
4727 let callback: P = callback.into_inner();
4728 callback(result);
4729 }
4730 }
4731 let callback = trash_async_trampoline::<P>;
4732 unsafe {
4733 ffi::g_file_trash_async(
4734 self.as_ref().to_glib_none().0,
4735 io_priority.into_glib(),
4736 cancellable.map(|p| p.as_ref()).to_glib_none().0,
4737 Some(callback),
4738 Box_::into_raw(user_data) as *mut _,
4739 );
4740 }
4741 }
4742
4743 fn trash_future(
4744 &self,
4745 io_priority: glib::Priority,
4746 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
4747 Box_::pin(crate::GioFuture::new(
4748 self,
4749 move |obj, cancellable, send| {
4750 obj.trash_async(io_priority, Some(cancellable), move |res| {
4751 send.resolve(res);
4752 });
4753 },
4754 ))
4755 }
4756
4757 /// Unmounts a file of type [`FileType::Mountable`][crate::FileType::Mountable].
4758 ///
4759 /// If @cancellable is not [`None`], then the operation can be cancelled by
4760 /// triggering the cancellable object from another thread. If the operation
4761 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4762 ///
4763 /// When the operation is finished, @callback will be called.
4764 /// You can then call g_file_unmount_mountable_finish() to get
4765 /// the result of the operation.
4766 /// ## `flags`
4767 /// flags affecting the operation
4768 /// ## `mount_operation`
4769 /// a #GMountOperation,
4770 /// or [`None`] to avoid user interaction
4771 /// ## `cancellable`
4772 /// optional #GCancellable object,
4773 /// [`None`] to ignore
4774 /// ## `callback`
4775 /// a #GAsyncReadyCallback
4776 /// to call when the request is satisfied
4777 #[doc(alias = "g_file_unmount_mountable_with_operation")]
4778 fn unmount_mountable_with_operation<P: FnOnce(Result<(), glib::Error>) + 'static>(
4779 &self,
4780 flags: MountUnmountFlags,
4781 mount_operation: Option<&impl IsA<MountOperation>>,
4782 cancellable: Option<&impl IsA<Cancellable>>,
4783 callback: P,
4784 ) {
4785 let main_context = glib::MainContext::ref_thread_default();
4786 let is_main_context_owner = main_context.is_owner();
4787 let has_acquired_main_context = (!is_main_context_owner)
4788 .then(|| main_context.acquire().ok())
4789 .flatten();
4790 assert!(
4791 is_main_context_owner || has_acquired_main_context.is_some(),
4792 "Async operations only allowed if the thread is owning the MainContext"
4793 );
4794
4795 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
4796 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
4797 unsafe extern "C" fn unmount_mountable_with_operation_trampoline<
4798 P: FnOnce(Result<(), glib::Error>) + 'static,
4799 >(
4800 _source_object: *mut glib::gobject_ffi::GObject,
4801 res: *mut crate::ffi::GAsyncResult,
4802 user_data: glib::ffi::gpointer,
4803 ) {
4804 unsafe {
4805 let mut error = std::ptr::null_mut();
4806 ffi::g_file_unmount_mountable_with_operation_finish(
4807 _source_object as *mut _,
4808 res,
4809 &mut error,
4810 );
4811 let result = if error.is_null() {
4812 Ok(())
4813 } else {
4814 Err(from_glib_full(error))
4815 };
4816 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
4817 Box_::from_raw(user_data as *mut _);
4818 let callback: P = callback.into_inner();
4819 callback(result);
4820 }
4821 }
4822 let callback = unmount_mountable_with_operation_trampoline::<P>;
4823 unsafe {
4824 ffi::g_file_unmount_mountable_with_operation(
4825 self.as_ref().to_glib_none().0,
4826 flags.into_glib(),
4827 mount_operation.map(|p| p.as_ref()).to_glib_none().0,
4828 cancellable.map(|p| p.as_ref()).to_glib_none().0,
4829 Some(callback),
4830 Box_::into_raw(user_data) as *mut _,
4831 );
4832 }
4833 }
4834
4835 fn unmount_mountable_with_operation_future(
4836 &self,
4837 flags: MountUnmountFlags,
4838 mount_operation: Option<&(impl IsA<MountOperation> + Clone + 'static)>,
4839 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
4840 let mount_operation = mount_operation.map(ToOwned::to_owned);
4841 Box_::pin(crate::GioFuture::new(
4842 self,
4843 move |obj, cancellable, send| {
4844 obj.unmount_mountable_with_operation(
4845 flags,
4846 mount_operation.as_ref().map(::std::borrow::Borrow::borrow),
4847 Some(cancellable),
4848 move |res| {
4849 send.resolve(res);
4850 },
4851 );
4852 },
4853 ))
4854 }
4855}
4856
4857impl<O: IsA<File>> FileExt for O {}