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