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