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 [`FileEnumerator`][crate::FileEnumerator] object that will give out
1097 /// [`FileInfo`][crate::FileInfo] 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`. `FILE_ATTRIBUTE_STANDARD_NAME` should
1109 /// always be specified if you plan to call [`FileEnumeratorExt::child()`][crate::prelude::FileEnumeratorExt::child()] or
1110 /// `FileEnumerator::iterate()` on the returned enumerator.
1111 ///
1112 /// If @cancellable is not `NULL`, then the operation can be cancelled
1113 /// by triggering the cancellable object from another thread. If the
1114 /// operation was cancelled, the error [error@Gio.IOErrorEnum.CANCELLED] will be
1115 /// returned.
1116 ///
1117 /// If the file does not exist, the [error@Gio.IOErrorEnum.NOT_FOUND] error will
1118 /// be returned. If the file is not a directory, the [error@Gio.IOErrorEnum.NOT_DIRECTORY]
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 `GObject::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 /// Same as g_file_replace_contents_async() but takes a #GBytes input instead.
3573 /// This function will keep a ref on @contents until the operation is done.
3574 /// Unlike g_file_replace_contents_async() this allows forgetting about the
3575 /// content without waiting for the callback.
3576 ///
3577 /// When this operation has completed, @callback will be called with
3578 /// @user_user data, and the operation can be finalized with
3579 /// g_file_replace_contents_finish().
3580 /// ## `contents`
3581 /// a #GBytes
3582 /// ## `etag`
3583 /// a new [entity tag](#entity-tags) for the @self, or [`None`]
3584 /// ## `make_backup`
3585 /// [`true`] if a backup should be created
3586 /// ## `flags`
3587 /// a set of #GFileCreateFlags
3588 /// ## `cancellable`
3589 /// optional #GCancellable object, [`None`] to ignore
3590 /// ## `callback`
3591 /// a #GAsyncReadyCallback to call when the request is satisfied
3592 #[doc(alias = "g_file_replace_contents_bytes_async")]
3593 fn replace_contents_bytes_async<
3594 P: FnOnce(Result<Option<glib::GString>, glib::Error>) + 'static,
3595 >(
3596 &self,
3597 contents: &glib::Bytes,
3598 etag: Option<&str>,
3599 make_backup: bool,
3600 flags: FileCreateFlags,
3601 cancellable: Option<&impl IsA<Cancellable>>,
3602 callback: P,
3603 ) {
3604 let main_context = glib::MainContext::ref_thread_default();
3605 let is_main_context_owner = main_context.is_owner();
3606 let has_acquired_main_context = (!is_main_context_owner)
3607 .then(|| main_context.acquire().ok())
3608 .flatten();
3609 assert!(
3610 is_main_context_owner || has_acquired_main_context.is_some(),
3611 "Async operations only allowed if the thread is owning the MainContext"
3612 );
3613
3614 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
3615 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
3616 unsafe extern "C" fn replace_contents_bytes_async_trampoline<
3617 P: FnOnce(Result<Option<glib::GString>, glib::Error>) + 'static,
3618 >(
3619 _source_object: *mut glib::gobject_ffi::GObject,
3620 res: *mut crate::ffi::GAsyncResult,
3621 user_data: glib::ffi::gpointer,
3622 ) {
3623 unsafe {
3624 let mut error = std::ptr::null_mut();
3625 let mut new_etag = std::ptr::null_mut();
3626 ffi::g_file_replace_contents_finish(
3627 _source_object as *mut _,
3628 res,
3629 &mut new_etag,
3630 &mut error,
3631 );
3632 let result = if error.is_null() {
3633 Ok(from_glib_full(new_etag))
3634 } else {
3635 Err(from_glib_full(error))
3636 };
3637 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
3638 Box_::from_raw(user_data as *mut _);
3639 let callback: P = callback.into_inner();
3640 callback(result);
3641 }
3642 }
3643 let callback = replace_contents_bytes_async_trampoline::<P>;
3644 unsafe {
3645 ffi::g_file_replace_contents_bytes_async(
3646 self.as_ref().to_glib_none().0,
3647 contents.to_glib_none().0,
3648 etag.to_glib_none().0,
3649 make_backup.into_glib(),
3650 flags.into_glib(),
3651 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3652 Some(callback),
3653 Box_::into_raw(user_data) as *mut _,
3654 );
3655 }
3656 }
3657
3658 fn replace_contents_bytes_future(
3659 &self,
3660 contents: &glib::Bytes,
3661 etag: Option<&str>,
3662 make_backup: bool,
3663 flags: FileCreateFlags,
3664 ) -> Pin<
3665 Box_<
3666 dyn std::future::Future<Output = Result<Option<glib::GString>, glib::Error>> + 'static,
3667 >,
3668 > {
3669 let contents = contents.clone();
3670 let etag = etag.map(ToOwned::to_owned);
3671 Box_::pin(crate::GioFuture::new(
3672 self,
3673 move |obj, cancellable, send| {
3674 obj.replace_contents_bytes_async(
3675 &contents,
3676 etag.as_ref().map(::std::borrow::Borrow::borrow),
3677 make_backup,
3678 flags,
3679 Some(cancellable),
3680 move |res| {
3681 send.resolve(res);
3682 },
3683 );
3684 },
3685 ))
3686 }
3687
3688 /// Returns an output stream for overwriting the file in readwrite mode,
3689 /// possibly creating a backup copy of the file first. If the file doesn't
3690 /// exist, it will be created.
3691 ///
3692 /// For details about the behaviour, see g_file_replace() which does the
3693 /// same thing but returns an output stream only.
3694 ///
3695 /// Note that in many non-local file cases read and write streams are not
3696 /// supported, so make sure you really need to do read and write streaming,
3697 /// rather than just opening for reading or writing.
3698 /// ## `etag`
3699 /// an optional [entity tag](#entity-tags)
3700 /// for the current #GFile, or #NULL to ignore
3701 /// ## `make_backup`
3702 /// [`true`] if a backup should be created
3703 /// ## `flags`
3704 /// a set of #GFileCreateFlags
3705 /// ## `cancellable`
3706 /// optional #GCancellable object,
3707 /// [`None`] to ignore
3708 ///
3709 /// # Returns
3710 ///
3711 /// a #GFileIOStream or [`None`] on error.
3712 /// Free the returned object with g_object_unref().
3713 #[doc(alias = "g_file_replace_readwrite")]
3714 fn replace_readwrite(
3715 &self,
3716 etag: Option<&str>,
3717 make_backup: bool,
3718 flags: FileCreateFlags,
3719 cancellable: Option<&impl IsA<Cancellable>>,
3720 ) -> Result<FileIOStream, glib::Error> {
3721 unsafe {
3722 let mut error = std::ptr::null_mut();
3723 let ret = ffi::g_file_replace_readwrite(
3724 self.as_ref().to_glib_none().0,
3725 etag.to_glib_none().0,
3726 make_backup.into_glib(),
3727 flags.into_glib(),
3728 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3729 &mut error,
3730 );
3731 if error.is_null() {
3732 Ok(from_glib_full(ret))
3733 } else {
3734 Err(from_glib_full(error))
3735 }
3736 }
3737 }
3738
3739 /// Asynchronously overwrites the file in read-write mode,
3740 /// replacing the contents, possibly creating a backup copy
3741 /// of the file first.
3742 ///
3743 /// For more details, see g_file_replace_readwrite() which is
3744 /// the synchronous version of this call.
3745 ///
3746 /// When the operation is finished, @callback will be called.
3747 /// You can then call g_file_replace_readwrite_finish() to get
3748 /// the result of the operation.
3749 /// ## `etag`
3750 /// an [entity tag](#entity-tags) for the current #GFile,
3751 /// or [`None`] to ignore
3752 /// ## `make_backup`
3753 /// [`true`] if a backup should be created
3754 /// ## `flags`
3755 /// a set of #GFileCreateFlags
3756 /// ## `io_priority`
3757 /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
3758 /// ## `cancellable`
3759 /// optional #GCancellable object,
3760 /// [`None`] to ignore
3761 /// ## `callback`
3762 /// a #GAsyncReadyCallback
3763 /// to call when the request is satisfied
3764 #[doc(alias = "g_file_replace_readwrite_async")]
3765 fn replace_readwrite_async<P: FnOnce(Result<FileIOStream, glib::Error>) + 'static>(
3766 &self,
3767 etag: Option<&str>,
3768 make_backup: bool,
3769 flags: FileCreateFlags,
3770 io_priority: glib::Priority,
3771 cancellable: Option<&impl IsA<Cancellable>>,
3772 callback: P,
3773 ) {
3774 let main_context = glib::MainContext::ref_thread_default();
3775 let is_main_context_owner = main_context.is_owner();
3776 let has_acquired_main_context = (!is_main_context_owner)
3777 .then(|| main_context.acquire().ok())
3778 .flatten();
3779 assert!(
3780 is_main_context_owner || has_acquired_main_context.is_some(),
3781 "Async operations only allowed if the thread is owning the MainContext"
3782 );
3783
3784 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
3785 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
3786 unsafe extern "C" fn replace_readwrite_async_trampoline<
3787 P: FnOnce(Result<FileIOStream, glib::Error>) + 'static,
3788 >(
3789 _source_object: *mut glib::gobject_ffi::GObject,
3790 res: *mut crate::ffi::GAsyncResult,
3791 user_data: glib::ffi::gpointer,
3792 ) {
3793 unsafe {
3794 let mut error = std::ptr::null_mut();
3795 let ret =
3796 ffi::g_file_replace_readwrite_finish(_source_object as *mut _, res, &mut error);
3797 let result = if error.is_null() {
3798 Ok(from_glib_full(ret))
3799 } else {
3800 Err(from_glib_full(error))
3801 };
3802 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
3803 Box_::from_raw(user_data as *mut _);
3804 let callback: P = callback.into_inner();
3805 callback(result);
3806 }
3807 }
3808 let callback = replace_readwrite_async_trampoline::<P>;
3809 unsafe {
3810 ffi::g_file_replace_readwrite_async(
3811 self.as_ref().to_glib_none().0,
3812 etag.to_glib_none().0,
3813 make_backup.into_glib(),
3814 flags.into_glib(),
3815 io_priority.into_glib(),
3816 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3817 Some(callback),
3818 Box_::into_raw(user_data) as *mut _,
3819 );
3820 }
3821 }
3822
3823 fn replace_readwrite_future(
3824 &self,
3825 etag: Option<&str>,
3826 make_backup: bool,
3827 flags: FileCreateFlags,
3828 io_priority: glib::Priority,
3829 ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileIOStream, glib::Error>> + 'static>>
3830 {
3831 let etag = etag.map(ToOwned::to_owned);
3832 Box_::pin(crate::GioFuture::new(
3833 self,
3834 move |obj, cancellable, send| {
3835 obj.replace_readwrite_async(
3836 etag.as_ref().map(::std::borrow::Borrow::borrow),
3837 make_backup,
3838 flags,
3839 io_priority,
3840 Some(cancellable),
3841 move |res| {
3842 send.resolve(res);
3843 },
3844 );
3845 },
3846 ))
3847 }
3848
3849 /// Resolves a relative path for @self to an absolute path.
3850 ///
3851 /// This call does no blocking I/O.
3852 ///
3853 /// If the @relative_path is an absolute path name, the resolution
3854 /// is done absolutely (without taking @self path as base).
3855 /// ## `relative_path`
3856 /// a given relative path string
3857 ///
3858 /// # Returns
3859 ///
3860 /// a #GFile for the resolved path.
3861 #[doc(alias = "g_file_resolve_relative_path")]
3862 #[must_use]
3863 fn resolve_relative_path(&self, relative_path: impl AsRef<std::path::Path>) -> File {
3864 unsafe {
3865 from_glib_full(ffi::g_file_resolve_relative_path(
3866 self.as_ref().to_glib_none().0,
3867 relative_path.as_ref().to_glib_none().0,
3868 ))
3869 }
3870 }
3871
3872 //#[doc(alias = "g_file_set_attribute")]
3873 //fn set_attribute(&self, attribute: &str, type_: FileAttributeType, value_p: /*Unimplemented*/Option<Basic: Pointer>, flags: FileQueryInfoFlags, cancellable: Option<&impl IsA<Cancellable>>) -> Result<(), glib::Error> {
3874 // unsafe { TODO: call ffi:g_file_set_attribute() }
3875 //}
3876
3877 /// Sets @attribute of type [`FileAttributeType::ByteString`][crate::FileAttributeType::ByteString] to @value.
3878 /// If @attribute is of a different type, this operation will fail,
3879 /// returning [`false`].
3880 ///
3881 /// If @cancellable is not [`None`], then the operation can be cancelled by
3882 /// triggering the cancellable object from another thread. If the operation
3883 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3884 /// ## `attribute`
3885 /// a string containing the attribute's name
3886 /// ## `value`
3887 /// a string containing the attribute's new value
3888 /// ## `flags`
3889 /// a #GFileQueryInfoFlags
3890 /// ## `cancellable`
3891 /// optional #GCancellable object,
3892 /// [`None`] to ignore
3893 ///
3894 /// # Returns
3895 ///
3896 /// [`true`] if the @attribute was successfully set to @value
3897 /// in the @self, [`false`] otherwise.
3898 #[doc(alias = "g_file_set_attribute_byte_string")]
3899 fn set_attribute_byte_string(
3900 &self,
3901 attribute: &str,
3902 value: &str,
3903 flags: FileQueryInfoFlags,
3904 cancellable: Option<&impl IsA<Cancellable>>,
3905 ) -> Result<(), glib::Error> {
3906 unsafe {
3907 let mut error = std::ptr::null_mut();
3908 let is_ok = ffi::g_file_set_attribute_byte_string(
3909 self.as_ref().to_glib_none().0,
3910 attribute.to_glib_none().0,
3911 value.to_glib_none().0,
3912 flags.into_glib(),
3913 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3914 &mut error,
3915 );
3916 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
3917 if error.is_null() {
3918 Ok(())
3919 } else {
3920 Err(from_glib_full(error))
3921 }
3922 }
3923 }
3924
3925 /// Sets @attribute of type [`FileAttributeType::Int32`][crate::FileAttributeType::Int32] to @value.
3926 /// If @attribute is of a different type, this operation will fail.
3927 ///
3928 /// If @cancellable is not [`None`], then the operation can be cancelled by
3929 /// triggering the cancellable object from another thread. If the operation
3930 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3931 /// ## `attribute`
3932 /// a string containing the attribute's name
3933 /// ## `value`
3934 /// a #gint32 containing the attribute's new value
3935 /// ## `flags`
3936 /// a #GFileQueryInfoFlags
3937 /// ## `cancellable`
3938 /// optional #GCancellable object,
3939 /// [`None`] to ignore
3940 ///
3941 /// # Returns
3942 ///
3943 /// [`true`] if the @attribute was successfully set to @value
3944 /// in the @self, [`false`] otherwise.
3945 #[doc(alias = "g_file_set_attribute_int32")]
3946 fn set_attribute_int32(
3947 &self,
3948 attribute: &str,
3949 value: i32,
3950 flags: FileQueryInfoFlags,
3951 cancellable: Option<&impl IsA<Cancellable>>,
3952 ) -> Result<(), glib::Error> {
3953 unsafe {
3954 let mut error = std::ptr::null_mut();
3955 let is_ok = ffi::g_file_set_attribute_int32(
3956 self.as_ref().to_glib_none().0,
3957 attribute.to_glib_none().0,
3958 value,
3959 flags.into_glib(),
3960 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3961 &mut error,
3962 );
3963 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
3964 if error.is_null() {
3965 Ok(())
3966 } else {
3967 Err(from_glib_full(error))
3968 }
3969 }
3970 }
3971
3972 /// Sets @attribute of type [`FileAttributeType::Int64`][crate::FileAttributeType::Int64] to @value.
3973 /// If @attribute is of a different type, this operation will fail.
3974 ///
3975 /// If @cancellable is not [`None`], then the operation can be cancelled by
3976 /// triggering the cancellable object from another thread. If the operation
3977 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3978 /// ## `attribute`
3979 /// a string containing the attribute's name
3980 /// ## `value`
3981 /// a #guint64 containing the attribute's new value
3982 /// ## `flags`
3983 /// a #GFileQueryInfoFlags
3984 /// ## `cancellable`
3985 /// optional #GCancellable object,
3986 /// [`None`] to ignore
3987 ///
3988 /// # Returns
3989 ///
3990 /// [`true`] if the @attribute was successfully set, [`false`] otherwise.
3991 #[doc(alias = "g_file_set_attribute_int64")]
3992 fn set_attribute_int64(
3993 &self,
3994 attribute: &str,
3995 value: i64,
3996 flags: FileQueryInfoFlags,
3997 cancellable: Option<&impl IsA<Cancellable>>,
3998 ) -> Result<(), glib::Error> {
3999 unsafe {
4000 let mut error = std::ptr::null_mut();
4001 let is_ok = ffi::g_file_set_attribute_int64(
4002 self.as_ref().to_glib_none().0,
4003 attribute.to_glib_none().0,
4004 value,
4005 flags.into_glib(),
4006 cancellable.map(|p| p.as_ref()).to_glib_none().0,
4007 &mut error,
4008 );
4009 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
4010 if error.is_null() {
4011 Ok(())
4012 } else {
4013 Err(from_glib_full(error))
4014 }
4015 }
4016 }
4017
4018 /// Sets @attribute of type [`FileAttributeType::String`][crate::FileAttributeType::String] to @value.
4019 /// If @attribute is of a different type, this operation will fail.
4020 ///
4021 /// If @cancellable is not [`None`], then the operation can be cancelled by
4022 /// triggering the cancellable object from another thread. If the operation
4023 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4024 /// ## `attribute`
4025 /// a string containing the attribute's name
4026 /// ## `value`
4027 /// a string containing the attribute's value
4028 /// ## `flags`
4029 /// #GFileQueryInfoFlags
4030 /// ## `cancellable`
4031 /// optional #GCancellable object,
4032 /// [`None`] to ignore
4033 ///
4034 /// # Returns
4035 ///
4036 /// [`true`] if the @attribute was successfully set, [`false`] otherwise.
4037 #[doc(alias = "g_file_set_attribute_string")]
4038 fn set_attribute_string(
4039 &self,
4040 attribute: &str,
4041 value: &str,
4042 flags: FileQueryInfoFlags,
4043 cancellable: Option<&impl IsA<Cancellable>>,
4044 ) -> Result<(), glib::Error> {
4045 unsafe {
4046 let mut error = std::ptr::null_mut();
4047 let is_ok = ffi::g_file_set_attribute_string(
4048 self.as_ref().to_glib_none().0,
4049 attribute.to_glib_none().0,
4050 value.to_glib_none().0,
4051 flags.into_glib(),
4052 cancellable.map(|p| p.as_ref()).to_glib_none().0,
4053 &mut error,
4054 );
4055 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
4056 if error.is_null() {
4057 Ok(())
4058 } else {
4059 Err(from_glib_full(error))
4060 }
4061 }
4062 }
4063
4064 /// Sets @attribute of type [`FileAttributeType::Uint32`][crate::FileAttributeType::Uint32] to @value.
4065 /// If @attribute is of a different type, this operation will fail.
4066 ///
4067 /// If @cancellable is not [`None`], then the operation can be cancelled by
4068 /// triggering the cancellable object from another thread. If the operation
4069 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4070 /// ## `attribute`
4071 /// a string containing the attribute's name
4072 /// ## `value`
4073 /// a #guint32 containing the attribute's new value
4074 /// ## `flags`
4075 /// a #GFileQueryInfoFlags
4076 /// ## `cancellable`
4077 /// optional #GCancellable object,
4078 /// [`None`] to ignore
4079 ///
4080 /// # Returns
4081 ///
4082 /// [`true`] if the @attribute was successfully set to @value
4083 /// in the @self, [`false`] otherwise.
4084 #[doc(alias = "g_file_set_attribute_uint32")]
4085 fn set_attribute_uint32(
4086 &self,
4087 attribute: &str,
4088 value: u32,
4089 flags: FileQueryInfoFlags,
4090 cancellable: Option<&impl IsA<Cancellable>>,
4091 ) -> Result<(), glib::Error> {
4092 unsafe {
4093 let mut error = std::ptr::null_mut();
4094 let is_ok = ffi::g_file_set_attribute_uint32(
4095 self.as_ref().to_glib_none().0,
4096 attribute.to_glib_none().0,
4097 value,
4098 flags.into_glib(),
4099 cancellable.map(|p| p.as_ref()).to_glib_none().0,
4100 &mut error,
4101 );
4102 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
4103 if error.is_null() {
4104 Ok(())
4105 } else {
4106 Err(from_glib_full(error))
4107 }
4108 }
4109 }
4110
4111 /// Sets @attribute of type [`FileAttributeType::Uint64`][crate::FileAttributeType::Uint64] to @value.
4112 /// If @attribute is of a different type, this operation will fail.
4113 ///
4114 /// If @cancellable is not [`None`], then the operation can be cancelled by
4115 /// triggering the cancellable object from another thread. If the operation
4116 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4117 /// ## `attribute`
4118 /// a string containing the attribute's name
4119 /// ## `value`
4120 /// a #guint64 containing the attribute's new value
4121 /// ## `flags`
4122 /// a #GFileQueryInfoFlags
4123 /// ## `cancellable`
4124 /// optional #GCancellable object,
4125 /// [`None`] to ignore
4126 ///
4127 /// # Returns
4128 ///
4129 /// [`true`] if the @attribute was successfully set to @value
4130 /// in the @self, [`false`] otherwise.
4131 #[doc(alias = "g_file_set_attribute_uint64")]
4132 fn set_attribute_uint64(
4133 &self,
4134 attribute: &str,
4135 value: u64,
4136 flags: FileQueryInfoFlags,
4137 cancellable: Option<&impl IsA<Cancellable>>,
4138 ) -> Result<(), glib::Error> {
4139 unsafe {
4140 let mut error = std::ptr::null_mut();
4141 let is_ok = ffi::g_file_set_attribute_uint64(
4142 self.as_ref().to_glib_none().0,
4143 attribute.to_glib_none().0,
4144 value,
4145 flags.into_glib(),
4146 cancellable.map(|p| p.as_ref()).to_glib_none().0,
4147 &mut error,
4148 );
4149 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
4150 if error.is_null() {
4151 Ok(())
4152 } else {
4153 Err(from_glib_full(error))
4154 }
4155 }
4156 }
4157
4158 /// Asynchronously sets the attributes of @self with @info.
4159 ///
4160 /// For more details, see g_file_set_attributes_from_info(),
4161 /// which is the synchronous version of this call.
4162 ///
4163 /// When the operation is finished, @callback will be called.
4164 /// You can then call g_file_set_attributes_finish() to get
4165 /// the result of the operation.
4166 /// ## `info`
4167 /// a #GFileInfo
4168 /// ## `flags`
4169 /// a #GFileQueryInfoFlags
4170 /// ## `io_priority`
4171 /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
4172 /// ## `cancellable`
4173 /// optional #GCancellable object,
4174 /// [`None`] to ignore
4175 /// ## `callback`
4176 /// a #GAsyncReadyCallback
4177 /// to call when the request is satisfied
4178 #[doc(alias = "g_file_set_attributes_async")]
4179 fn set_attributes_async<P: FnOnce(Result<FileInfo, glib::Error>) + 'static>(
4180 &self,
4181 info: &FileInfo,
4182 flags: FileQueryInfoFlags,
4183 io_priority: glib::Priority,
4184 cancellable: Option<&impl IsA<Cancellable>>,
4185 callback: P,
4186 ) {
4187 let main_context = glib::MainContext::ref_thread_default();
4188 let is_main_context_owner = main_context.is_owner();
4189 let has_acquired_main_context = (!is_main_context_owner)
4190 .then(|| main_context.acquire().ok())
4191 .flatten();
4192 assert!(
4193 is_main_context_owner || has_acquired_main_context.is_some(),
4194 "Async operations only allowed if the thread is owning the MainContext"
4195 );
4196
4197 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
4198 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
4199 unsafe extern "C" fn set_attributes_async_trampoline<
4200 P: FnOnce(Result<FileInfo, glib::Error>) + 'static,
4201 >(
4202 _source_object: *mut glib::gobject_ffi::GObject,
4203 res: *mut crate::ffi::GAsyncResult,
4204 user_data: glib::ffi::gpointer,
4205 ) {
4206 unsafe {
4207 let mut error = std::ptr::null_mut();
4208 let mut info = std::ptr::null_mut();
4209 ffi::g_file_set_attributes_finish(
4210 _source_object as *mut _,
4211 res,
4212 &mut info,
4213 &mut error,
4214 );
4215 let result = if error.is_null() {
4216 Ok(from_glib_full(info))
4217 } else {
4218 Err(from_glib_full(error))
4219 };
4220 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
4221 Box_::from_raw(user_data as *mut _);
4222 let callback: P = callback.into_inner();
4223 callback(result);
4224 }
4225 }
4226 let callback = set_attributes_async_trampoline::<P>;
4227 unsafe {
4228 ffi::g_file_set_attributes_async(
4229 self.as_ref().to_glib_none().0,
4230 info.to_glib_none().0,
4231 flags.into_glib(),
4232 io_priority.into_glib(),
4233 cancellable.map(|p| p.as_ref()).to_glib_none().0,
4234 Some(callback),
4235 Box_::into_raw(user_data) as *mut _,
4236 );
4237 }
4238 }
4239
4240 fn set_attributes_future(
4241 &self,
4242 info: &FileInfo,
4243 flags: FileQueryInfoFlags,
4244 io_priority: glib::Priority,
4245 ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileInfo, glib::Error>> + 'static>> {
4246 let info = info.clone();
4247 Box_::pin(crate::GioFuture::new(
4248 self,
4249 move |obj, cancellable, send| {
4250 obj.set_attributes_async(
4251 &info,
4252 flags,
4253 io_priority,
4254 Some(cancellable),
4255 move |res| {
4256 send.resolve(res);
4257 },
4258 );
4259 },
4260 ))
4261 }
4262
4263 /// Tries to set all attributes in the #GFileInfo on the target
4264 /// values, not stopping on the first error.
4265 ///
4266 /// If there is any error during this operation then @error will
4267 /// be set to the first error. Error on particular fields are flagged
4268 /// by setting the "status" field in the attribute value to
4269 /// [`FileAttributeStatus::ErrorSetting`][crate::FileAttributeStatus::ErrorSetting], which means you can
4270 /// also detect further errors.
4271 ///
4272 /// If @cancellable is not [`None`], then the operation can be cancelled by
4273 /// triggering the cancellable object from another thread. If the operation
4274 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4275 /// ## `info`
4276 /// a #GFileInfo
4277 /// ## `flags`
4278 /// #GFileQueryInfoFlags
4279 /// ## `cancellable`
4280 /// optional #GCancellable object,
4281 /// [`None`] to ignore
4282 ///
4283 /// # Returns
4284 ///
4285 /// [`false`] if there was any error, [`true`] otherwise.
4286 #[doc(alias = "g_file_set_attributes_from_info")]
4287 fn set_attributes_from_info(
4288 &self,
4289 info: &FileInfo,
4290 flags: FileQueryInfoFlags,
4291 cancellable: Option<&impl IsA<Cancellable>>,
4292 ) -> Result<(), glib::Error> {
4293 unsafe {
4294 let mut error = std::ptr::null_mut();
4295 let is_ok = ffi::g_file_set_attributes_from_info(
4296 self.as_ref().to_glib_none().0,
4297 info.to_glib_none().0,
4298 flags.into_glib(),
4299 cancellable.map(|p| p.as_ref()).to_glib_none().0,
4300 &mut error,
4301 );
4302 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
4303 if error.is_null() {
4304 Ok(())
4305 } else {
4306 Err(from_glib_full(error))
4307 }
4308 }
4309 }
4310
4311 /// Renames @self to the specified display name.
4312 ///
4313 /// The display name is converted from UTF-8 to the correct encoding
4314 /// for the target filesystem if possible and the @self is renamed to this.
4315 ///
4316 /// If you want to implement a rename operation in the user interface the
4317 /// edit name ([`FILE_ATTRIBUTE_STANDARD_EDIT_NAME`][crate::FILE_ATTRIBUTE_STANDARD_EDIT_NAME]) should be used as the
4318 /// initial value in the rename widget, and then the result after editing
4319 /// should be passed to g_file_set_display_name().
4320 ///
4321 /// On success the resulting converted filename is returned.
4322 ///
4323 /// If @cancellable is not [`None`], then the operation can be cancelled by
4324 /// triggering the cancellable object from another thread. If the operation
4325 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4326 /// ## `display_name`
4327 /// a string
4328 /// ## `cancellable`
4329 /// optional #GCancellable object,
4330 /// [`None`] to ignore
4331 ///
4332 /// # Returns
4333 ///
4334 /// a #GFile specifying what @self was renamed to,
4335 /// or [`None`] if there was an error.
4336 /// Free the returned object with g_object_unref().
4337 #[doc(alias = "g_file_set_display_name")]
4338 fn set_display_name(
4339 &self,
4340 display_name: &str,
4341 cancellable: Option<&impl IsA<Cancellable>>,
4342 ) -> Result<File, glib::Error> {
4343 unsafe {
4344 let mut error = std::ptr::null_mut();
4345 let ret = ffi::g_file_set_display_name(
4346 self.as_ref().to_glib_none().0,
4347 display_name.to_glib_none().0,
4348 cancellable.map(|p| p.as_ref()).to_glib_none().0,
4349 &mut error,
4350 );
4351 if error.is_null() {
4352 Ok(from_glib_full(ret))
4353 } else {
4354 Err(from_glib_full(error))
4355 }
4356 }
4357 }
4358
4359 /// Asynchronously sets the display name for a given #GFile.
4360 ///
4361 /// For more details, see g_file_set_display_name() which is
4362 /// the synchronous version of this call.
4363 ///
4364 /// When the operation is finished, @callback will be called.
4365 /// You can then call g_file_set_display_name_finish() to get
4366 /// the result of the operation.
4367 /// ## `display_name`
4368 /// a string
4369 /// ## `io_priority`
4370 /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
4371 /// ## `cancellable`
4372 /// optional #GCancellable object,
4373 /// [`None`] to ignore
4374 /// ## `callback`
4375 /// a #GAsyncReadyCallback
4376 /// to call when the request is satisfied
4377 #[doc(alias = "g_file_set_display_name_async")]
4378 fn set_display_name_async<P: FnOnce(Result<File, glib::Error>) + 'static>(
4379 &self,
4380 display_name: &str,
4381 io_priority: glib::Priority,
4382 cancellable: Option<&impl IsA<Cancellable>>,
4383 callback: P,
4384 ) {
4385 let main_context = glib::MainContext::ref_thread_default();
4386 let is_main_context_owner = main_context.is_owner();
4387 let has_acquired_main_context = (!is_main_context_owner)
4388 .then(|| main_context.acquire().ok())
4389 .flatten();
4390 assert!(
4391 is_main_context_owner || has_acquired_main_context.is_some(),
4392 "Async operations only allowed if the thread is owning the MainContext"
4393 );
4394
4395 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
4396 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
4397 unsafe extern "C" fn set_display_name_async_trampoline<
4398 P: FnOnce(Result<File, glib::Error>) + 'static,
4399 >(
4400 _source_object: *mut glib::gobject_ffi::GObject,
4401 res: *mut crate::ffi::GAsyncResult,
4402 user_data: glib::ffi::gpointer,
4403 ) {
4404 unsafe {
4405 let mut error = std::ptr::null_mut();
4406 let ret =
4407 ffi::g_file_set_display_name_finish(_source_object as *mut _, res, &mut error);
4408 let result = if error.is_null() {
4409 Ok(from_glib_full(ret))
4410 } else {
4411 Err(from_glib_full(error))
4412 };
4413 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
4414 Box_::from_raw(user_data as *mut _);
4415 let callback: P = callback.into_inner();
4416 callback(result);
4417 }
4418 }
4419 let callback = set_display_name_async_trampoline::<P>;
4420 unsafe {
4421 ffi::g_file_set_display_name_async(
4422 self.as_ref().to_glib_none().0,
4423 display_name.to_glib_none().0,
4424 io_priority.into_glib(),
4425 cancellable.map(|p| p.as_ref()).to_glib_none().0,
4426 Some(callback),
4427 Box_::into_raw(user_data) as *mut _,
4428 );
4429 }
4430 }
4431
4432 fn set_display_name_future(
4433 &self,
4434 display_name: &str,
4435 io_priority: glib::Priority,
4436 ) -> Pin<Box_<dyn std::future::Future<Output = Result<File, glib::Error>> + 'static>> {
4437 let display_name = String::from(display_name);
4438 Box_::pin(crate::GioFuture::new(
4439 self,
4440 move |obj, cancellable, send| {
4441 obj.set_display_name_async(
4442 &display_name,
4443 io_priority,
4444 Some(cancellable),
4445 move |res| {
4446 send.resolve(res);
4447 },
4448 );
4449 },
4450 ))
4451 }
4452
4453 /// Starts a file of type [`FileType::Mountable`][crate::FileType::Mountable].
4454 /// Using @start_operation, you can request callbacks when, for instance,
4455 /// passwords are needed during authentication.
4456 ///
4457 /// If @cancellable is not [`None`], then the operation can be cancelled by
4458 /// triggering the cancellable object from another thread. If the operation
4459 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4460 ///
4461 /// When the operation is finished, @callback will be called.
4462 /// You can then call g_file_mount_mountable_finish() to get
4463 /// the result of the operation.
4464 /// ## `flags`
4465 /// flags affecting the operation
4466 /// ## `start_operation`
4467 /// a #GMountOperation, or [`None`] to avoid user interaction
4468 /// ## `cancellable`
4469 /// optional #GCancellable object, [`None`] to ignore
4470 /// ## `callback`
4471 /// a #GAsyncReadyCallback to call when the request is satisfied, or [`None`]
4472 #[doc(alias = "g_file_start_mountable")]
4473 fn start_mountable<P: FnOnce(Result<(), glib::Error>) + 'static>(
4474 &self,
4475 flags: DriveStartFlags,
4476 start_operation: Option<&impl IsA<MountOperation>>,
4477 cancellable: Option<&impl IsA<Cancellable>>,
4478 callback: P,
4479 ) {
4480 let main_context = glib::MainContext::ref_thread_default();
4481 let is_main_context_owner = main_context.is_owner();
4482 let has_acquired_main_context = (!is_main_context_owner)
4483 .then(|| main_context.acquire().ok())
4484 .flatten();
4485 assert!(
4486 is_main_context_owner || has_acquired_main_context.is_some(),
4487 "Async operations only allowed if the thread is owning the MainContext"
4488 );
4489
4490 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
4491 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
4492 unsafe extern "C" fn start_mountable_trampoline<
4493 P: FnOnce(Result<(), glib::Error>) + 'static,
4494 >(
4495 _source_object: *mut glib::gobject_ffi::GObject,
4496 res: *mut crate::ffi::GAsyncResult,
4497 user_data: glib::ffi::gpointer,
4498 ) {
4499 unsafe {
4500 let mut error = std::ptr::null_mut();
4501 ffi::g_file_start_mountable_finish(_source_object as *mut _, res, &mut error);
4502 let result = if error.is_null() {
4503 Ok(())
4504 } else {
4505 Err(from_glib_full(error))
4506 };
4507 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
4508 Box_::from_raw(user_data as *mut _);
4509 let callback: P = callback.into_inner();
4510 callback(result);
4511 }
4512 }
4513 let callback = start_mountable_trampoline::<P>;
4514 unsafe {
4515 ffi::g_file_start_mountable(
4516 self.as_ref().to_glib_none().0,
4517 flags.into_glib(),
4518 start_operation.map(|p| p.as_ref()).to_glib_none().0,
4519 cancellable.map(|p| p.as_ref()).to_glib_none().0,
4520 Some(callback),
4521 Box_::into_raw(user_data) as *mut _,
4522 );
4523 }
4524 }
4525
4526 fn start_mountable_future(
4527 &self,
4528 flags: DriveStartFlags,
4529 start_operation: Option<&(impl IsA<MountOperation> + Clone + 'static)>,
4530 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
4531 let start_operation = start_operation.map(ToOwned::to_owned);
4532 Box_::pin(crate::GioFuture::new(
4533 self,
4534 move |obj, cancellable, send| {
4535 obj.start_mountable(
4536 flags,
4537 start_operation.as_ref().map(::std::borrow::Borrow::borrow),
4538 Some(cancellable),
4539 move |res| {
4540 send.resolve(res);
4541 },
4542 );
4543 },
4544 ))
4545 }
4546
4547 /// Stops a file of type [`FileType::Mountable`][crate::FileType::Mountable].
4548 ///
4549 /// If @cancellable is not [`None`], then the operation can be cancelled by
4550 /// triggering the cancellable object from another thread. If the operation
4551 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4552 ///
4553 /// When the operation is finished, @callback will be called.
4554 /// You can then call g_file_stop_mountable_finish() to get
4555 /// the result of the operation.
4556 /// ## `flags`
4557 /// flags affecting the operation
4558 /// ## `mount_operation`
4559 /// a #GMountOperation,
4560 /// or [`None`] to avoid user interaction.
4561 /// ## `cancellable`
4562 /// optional #GCancellable object,
4563 /// [`None`] to ignore
4564 /// ## `callback`
4565 /// a #GAsyncReadyCallback to call
4566 /// when the request is satisfied, or [`None`]
4567 #[doc(alias = "g_file_stop_mountable")]
4568 fn stop_mountable<P: FnOnce(Result<(), glib::Error>) + 'static>(
4569 &self,
4570 flags: MountUnmountFlags,
4571 mount_operation: Option<&impl IsA<MountOperation>>,
4572 cancellable: Option<&impl IsA<Cancellable>>,
4573 callback: P,
4574 ) {
4575 let main_context = glib::MainContext::ref_thread_default();
4576 let is_main_context_owner = main_context.is_owner();
4577 let has_acquired_main_context = (!is_main_context_owner)
4578 .then(|| main_context.acquire().ok())
4579 .flatten();
4580 assert!(
4581 is_main_context_owner || has_acquired_main_context.is_some(),
4582 "Async operations only allowed if the thread is owning the MainContext"
4583 );
4584
4585 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
4586 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
4587 unsafe extern "C" fn stop_mountable_trampoline<
4588 P: FnOnce(Result<(), glib::Error>) + 'static,
4589 >(
4590 _source_object: *mut glib::gobject_ffi::GObject,
4591 res: *mut crate::ffi::GAsyncResult,
4592 user_data: glib::ffi::gpointer,
4593 ) {
4594 unsafe {
4595 let mut error = std::ptr::null_mut();
4596 ffi::g_file_stop_mountable_finish(_source_object as *mut _, res, &mut error);
4597 let result = if error.is_null() {
4598 Ok(())
4599 } else {
4600 Err(from_glib_full(error))
4601 };
4602 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
4603 Box_::from_raw(user_data as *mut _);
4604 let callback: P = callback.into_inner();
4605 callback(result);
4606 }
4607 }
4608 let callback = stop_mountable_trampoline::<P>;
4609 unsafe {
4610 ffi::g_file_stop_mountable(
4611 self.as_ref().to_glib_none().0,
4612 flags.into_glib(),
4613 mount_operation.map(|p| p.as_ref()).to_glib_none().0,
4614 cancellable.map(|p| p.as_ref()).to_glib_none().0,
4615 Some(callback),
4616 Box_::into_raw(user_data) as *mut _,
4617 );
4618 }
4619 }
4620
4621 fn stop_mountable_future(
4622 &self,
4623 flags: MountUnmountFlags,
4624 mount_operation: Option<&(impl IsA<MountOperation> + Clone + 'static)>,
4625 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
4626 let mount_operation = mount_operation.map(ToOwned::to_owned);
4627 Box_::pin(crate::GioFuture::new(
4628 self,
4629 move |obj, cancellable, send| {
4630 obj.stop_mountable(
4631 flags,
4632 mount_operation.as_ref().map(::std::borrow::Borrow::borrow),
4633 Some(cancellable),
4634 move |res| {
4635 send.resolve(res);
4636 },
4637 );
4638 },
4639 ))
4640 }
4641
4642 /// Checks if @self supports thread-default main contexts
4643 /// (see [`glib::MainContext::push_thread_default()`][crate::glib::MainContext::push_thread_default()])
4644 /// If this returns [`false`], you cannot perform asynchronous operations on
4645 /// @self in a thread that has a thread-default context.
4646 ///
4647 /// # Returns
4648 ///
4649 /// Whether or not @self supports thread-default contexts.
4650 #[doc(alias = "g_file_supports_thread_contexts")]
4651 fn supports_thread_contexts(&self) -> bool {
4652 unsafe {
4653 from_glib(ffi::g_file_supports_thread_contexts(
4654 self.as_ref().to_glib_none().0,
4655 ))
4656 }
4657 }
4658
4659 /// Sends @self to the "Trashcan", if possible. This is similar to
4660 /// deleting it, but the user can recover it before emptying the trashcan.
4661 /// Trashing is disabled for system mounts by default (see
4662 /// g_unix_mount_entry_is_system_internal()), so this call can return the
4663 /// [`IOErrorEnum::NotSupported`][crate::IOErrorEnum::NotSupported] error. Since GLib 2.66, the `x-gvfs-notrash` unix
4664 /// mount option can be used to disable g_file_trash() support for particular
4665 /// mounts, the [`IOErrorEnum::NotSupported`][crate::IOErrorEnum::NotSupported] error will be returned in that case.
4666 /// Since 2.82, the `x-gvfs-trash` unix mount option can be used to enable
4667 /// g_file_trash() support for particular system mounts.
4668 ///
4669 /// If @cancellable is not [`None`], then the operation can be cancelled by
4670 /// triggering the cancellable object from another thread. If the operation
4671 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4672 /// ## `cancellable`
4673 /// optional #GCancellable object,
4674 /// [`None`] to ignore
4675 ///
4676 /// # Returns
4677 ///
4678 /// [`true`] on successful trash, [`false`] otherwise.
4679 #[doc(alias = "g_file_trash")]
4680 fn trash(&self, cancellable: Option<&impl IsA<Cancellable>>) -> Result<(), glib::Error> {
4681 unsafe {
4682 let mut error = std::ptr::null_mut();
4683 let is_ok = ffi::g_file_trash(
4684 self.as_ref().to_glib_none().0,
4685 cancellable.map(|p| p.as_ref()).to_glib_none().0,
4686 &mut error,
4687 );
4688 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
4689 if error.is_null() {
4690 Ok(())
4691 } else {
4692 Err(from_glib_full(error))
4693 }
4694 }
4695 }
4696
4697 /// Asynchronously sends @self to the Trash location, if possible.
4698 /// ## `io_priority`
4699 /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
4700 /// ## `cancellable`
4701 /// optional #GCancellable object,
4702 /// [`None`] to ignore
4703 /// ## `callback`
4704 /// a #GAsyncReadyCallback to call
4705 /// when the request is satisfied
4706 #[doc(alias = "g_file_trash_async")]
4707 fn trash_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
4708 &self,
4709 io_priority: glib::Priority,
4710 cancellable: Option<&impl IsA<Cancellable>>,
4711 callback: P,
4712 ) {
4713 let main_context = glib::MainContext::ref_thread_default();
4714 let is_main_context_owner = main_context.is_owner();
4715 let has_acquired_main_context = (!is_main_context_owner)
4716 .then(|| main_context.acquire().ok())
4717 .flatten();
4718 assert!(
4719 is_main_context_owner || has_acquired_main_context.is_some(),
4720 "Async operations only allowed if the thread is owning the MainContext"
4721 );
4722
4723 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
4724 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
4725 unsafe extern "C" fn trash_async_trampoline<
4726 P: FnOnce(Result<(), glib::Error>) + 'static,
4727 >(
4728 _source_object: *mut glib::gobject_ffi::GObject,
4729 res: *mut crate::ffi::GAsyncResult,
4730 user_data: glib::ffi::gpointer,
4731 ) {
4732 unsafe {
4733 let mut error = std::ptr::null_mut();
4734 ffi::g_file_trash_finish(_source_object as *mut _, res, &mut error);
4735 let result = if error.is_null() {
4736 Ok(())
4737 } else {
4738 Err(from_glib_full(error))
4739 };
4740 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
4741 Box_::from_raw(user_data as *mut _);
4742 let callback: P = callback.into_inner();
4743 callback(result);
4744 }
4745 }
4746 let callback = trash_async_trampoline::<P>;
4747 unsafe {
4748 ffi::g_file_trash_async(
4749 self.as_ref().to_glib_none().0,
4750 io_priority.into_glib(),
4751 cancellable.map(|p| p.as_ref()).to_glib_none().0,
4752 Some(callback),
4753 Box_::into_raw(user_data) as *mut _,
4754 );
4755 }
4756 }
4757
4758 fn trash_future(
4759 &self,
4760 io_priority: glib::Priority,
4761 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
4762 Box_::pin(crate::GioFuture::new(
4763 self,
4764 move |obj, cancellable, send| {
4765 obj.trash_async(io_priority, Some(cancellable), move |res| {
4766 send.resolve(res);
4767 });
4768 },
4769 ))
4770 }
4771
4772 /// Unmounts a file of type [`FileType::Mountable`][crate::FileType::Mountable].
4773 ///
4774 /// If @cancellable is not [`None`], then the operation can be cancelled by
4775 /// triggering the cancellable object from another thread. If the operation
4776 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4777 ///
4778 /// When the operation is finished, @callback will be called.
4779 /// You can then call g_file_unmount_mountable_finish() to get
4780 /// the result of the operation.
4781 /// ## `flags`
4782 /// flags affecting the operation
4783 /// ## `mount_operation`
4784 /// a #GMountOperation,
4785 /// or [`None`] to avoid user interaction
4786 /// ## `cancellable`
4787 /// optional #GCancellable object,
4788 /// [`None`] to ignore
4789 /// ## `callback`
4790 /// a #GAsyncReadyCallback
4791 /// to call when the request is satisfied
4792 #[doc(alias = "g_file_unmount_mountable_with_operation")]
4793 fn unmount_mountable_with_operation<P: FnOnce(Result<(), glib::Error>) + 'static>(
4794 &self,
4795 flags: MountUnmountFlags,
4796 mount_operation: Option<&impl IsA<MountOperation>>,
4797 cancellable: Option<&impl IsA<Cancellable>>,
4798 callback: P,
4799 ) {
4800 let main_context = glib::MainContext::ref_thread_default();
4801 let is_main_context_owner = main_context.is_owner();
4802 let has_acquired_main_context = (!is_main_context_owner)
4803 .then(|| main_context.acquire().ok())
4804 .flatten();
4805 assert!(
4806 is_main_context_owner || has_acquired_main_context.is_some(),
4807 "Async operations only allowed if the thread is owning the MainContext"
4808 );
4809
4810 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
4811 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
4812 unsafe extern "C" fn unmount_mountable_with_operation_trampoline<
4813 P: FnOnce(Result<(), glib::Error>) + 'static,
4814 >(
4815 _source_object: *mut glib::gobject_ffi::GObject,
4816 res: *mut crate::ffi::GAsyncResult,
4817 user_data: glib::ffi::gpointer,
4818 ) {
4819 unsafe {
4820 let mut error = std::ptr::null_mut();
4821 ffi::g_file_unmount_mountable_with_operation_finish(
4822 _source_object as *mut _,
4823 res,
4824 &mut error,
4825 );
4826 let result = if error.is_null() {
4827 Ok(())
4828 } else {
4829 Err(from_glib_full(error))
4830 };
4831 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
4832 Box_::from_raw(user_data as *mut _);
4833 let callback: P = callback.into_inner();
4834 callback(result);
4835 }
4836 }
4837 let callback = unmount_mountable_with_operation_trampoline::<P>;
4838 unsafe {
4839 ffi::g_file_unmount_mountable_with_operation(
4840 self.as_ref().to_glib_none().0,
4841 flags.into_glib(),
4842 mount_operation.map(|p| p.as_ref()).to_glib_none().0,
4843 cancellable.map(|p| p.as_ref()).to_glib_none().0,
4844 Some(callback),
4845 Box_::into_raw(user_data) as *mut _,
4846 );
4847 }
4848 }
4849
4850 fn unmount_mountable_with_operation_future(
4851 &self,
4852 flags: MountUnmountFlags,
4853 mount_operation: Option<&(impl IsA<MountOperation> + Clone + 'static)>,
4854 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
4855 let mount_operation = mount_operation.map(ToOwned::to_owned);
4856 Box_::pin(crate::GioFuture::new(
4857 self,
4858 move |obj, cancellable, send| {
4859 obj.unmount_mountable_with_operation(
4860 flags,
4861 mount_operation.as_ref().map(::std::borrow::Borrow::borrow),
4862 Some(cancellable),
4863 move |res| {
4864 send.resolve(res);
4865 },
4866 );
4867 },
4868 ))
4869 }
4870}
4871
4872impl<O: IsA<File>> FileExt for O {}