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