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 /// The result is a #GFileInfo object that contains key-value
2797 /// attributes (such as the type or size of the file).
2798 ///
2799 /// The @attributes value is a string that specifies the file
2800 /// attributes that should be gathered. It is not an error if
2801 /// it's not possible to read a particular requested attribute
2802 /// from a file - it just won't be set. @attributes should be a
2803 /// comma-separated list of attributes or attribute wildcards.
2804 /// The wildcard "*" means all attributes, and a wildcard like
2805 /// "standard::*" means all attributes in the standard namespace.
2806 /// An example attribute query be "standard::*,owner::user".
2807 /// The standard attributes are available as defines, like
2808 /// [`FILE_ATTRIBUTE_STANDARD_NAME`][crate::FILE_ATTRIBUTE_STANDARD_NAME].
2809 ///
2810 /// If @cancellable is not [`None`], then the operation can be cancelled
2811 /// by triggering the cancellable object from another thread. If the
2812 /// operation was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be
2813 /// returned.
2814 ///
2815 /// For symlinks, normally the information about the target of the
2816 /// symlink is returned, rather than information about the symlink
2817 /// itself. However if you pass [`FileQueryInfoFlags::NOFOLLOW_SYMLINKS`][crate::FileQueryInfoFlags::NOFOLLOW_SYMLINKS]
2818 /// in @flags the information about the symlink itself will be returned.
2819 /// Also, for symlinks that point to non-existing files the information
2820 /// about the symlink itself will be returned.
2821 ///
2822 /// If the file does not exist, the [`IOErrorEnum::NotFound`][crate::IOErrorEnum::NotFound] error will be
2823 /// returned. Other errors are possible too, and depend on what kind of
2824 /// filesystem the file is on.
2825 /// ## `attributes`
2826 /// an attribute query string
2827 /// ## `flags`
2828 /// a set of #GFileQueryInfoFlags
2829 /// ## `cancellable`
2830 /// optional #GCancellable object,
2831 /// [`None`] to ignore
2832 ///
2833 /// # Returns
2834 ///
2835 /// a #GFileInfo for the given @self, or [`None`]
2836 /// on error. Free the returned object with g_object_unref().
2837 #[doc(alias = "g_file_query_info")]
2838 fn query_info(
2839 &self,
2840 attributes: &str,
2841 flags: FileQueryInfoFlags,
2842 cancellable: Option<&impl IsA<Cancellable>>,
2843 ) -> Result<FileInfo, glib::Error> {
2844 unsafe {
2845 let mut error = std::ptr::null_mut();
2846 let ret = ffi::g_file_query_info(
2847 self.as_ref().to_glib_none().0,
2848 attributes.to_glib_none().0,
2849 flags.into_glib(),
2850 cancellable.map(|p| p.as_ref()).to_glib_none().0,
2851 &mut error,
2852 );
2853 if error.is_null() {
2854 Ok(from_glib_full(ret))
2855 } else {
2856 Err(from_glib_full(error))
2857 }
2858 }
2859 }
2860
2861 /// Asynchronously gets the requested information about specified @self.
2862 /// The result is a #GFileInfo object that contains key-value attributes
2863 /// (such as type or size for the file).
2864 ///
2865 /// For more details, see g_file_query_info() which is the synchronous
2866 /// version of this call.
2867 ///
2868 /// When the operation is finished, @callback will be called. You can
2869 /// then call g_file_query_info_finish() to get the result of the operation.
2870 /// ## `attributes`
2871 /// an attribute query string
2872 /// ## `flags`
2873 /// a set of #GFileQueryInfoFlags
2874 /// ## `io_priority`
2875 /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
2876 /// ## `cancellable`
2877 /// optional #GCancellable object,
2878 /// [`None`] to ignore
2879 /// ## `callback`
2880 /// a #GAsyncReadyCallback
2881 /// to call when the request is satisfied
2882 #[doc(alias = "g_file_query_info_async")]
2883 fn query_info_async<P: FnOnce(Result<FileInfo, glib::Error>) + 'static>(
2884 &self,
2885 attributes: &str,
2886 flags: FileQueryInfoFlags,
2887 io_priority: glib::Priority,
2888 cancellable: Option<&impl IsA<Cancellable>>,
2889 callback: P,
2890 ) {
2891 let main_context = glib::MainContext::ref_thread_default();
2892 let is_main_context_owner = main_context.is_owner();
2893 let has_acquired_main_context = (!is_main_context_owner)
2894 .then(|| main_context.acquire().ok())
2895 .flatten();
2896 assert!(
2897 is_main_context_owner || has_acquired_main_context.is_some(),
2898 "Async operations only allowed if the thread is owning the MainContext"
2899 );
2900
2901 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
2902 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
2903 unsafe extern "C" fn query_info_async_trampoline<
2904 P: FnOnce(Result<FileInfo, glib::Error>) + 'static,
2905 >(
2906 _source_object: *mut glib::gobject_ffi::GObject,
2907 res: *mut crate::ffi::GAsyncResult,
2908 user_data: glib::ffi::gpointer,
2909 ) {
2910 let mut error = std::ptr::null_mut();
2911 let ret = ffi::g_file_query_info_finish(_source_object as *mut _, res, &mut error);
2912 let result = if error.is_null() {
2913 Ok(from_glib_full(ret))
2914 } else {
2915 Err(from_glib_full(error))
2916 };
2917 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
2918 Box_::from_raw(user_data as *mut _);
2919 let callback: P = callback.into_inner();
2920 callback(result);
2921 }
2922 let callback = query_info_async_trampoline::<P>;
2923 unsafe {
2924 ffi::g_file_query_info_async(
2925 self.as_ref().to_glib_none().0,
2926 attributes.to_glib_none().0,
2927 flags.into_glib(),
2928 io_priority.into_glib(),
2929 cancellable.map(|p| p.as_ref()).to_glib_none().0,
2930 Some(callback),
2931 Box_::into_raw(user_data) as *mut _,
2932 );
2933 }
2934 }
2935
2936 fn query_info_future(
2937 &self,
2938 attributes: &str,
2939 flags: FileQueryInfoFlags,
2940 io_priority: glib::Priority,
2941 ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileInfo, glib::Error>> + 'static>> {
2942 let attributes = String::from(attributes);
2943 Box_::pin(crate::GioFuture::new(
2944 self,
2945 move |obj, cancellable, send| {
2946 obj.query_info_async(
2947 &attributes,
2948 flags,
2949 io_priority,
2950 Some(cancellable),
2951 move |res| {
2952 send.resolve(res);
2953 },
2954 );
2955 },
2956 ))
2957 }
2958
2959 /// Obtain the list of settable attributes for the file.
2960 ///
2961 /// Returns the type and full attribute name of all the attributes
2962 /// that can be set on this file. This doesn't mean setting it will
2963 /// always succeed though, you might get an access failure, or some
2964 /// specific file may not support a specific attribute.
2965 ///
2966 /// If @cancellable is not [`None`], then the operation can be cancelled by
2967 /// triggering the cancellable object from another thread. If the operation
2968 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
2969 /// ## `cancellable`
2970 /// optional #GCancellable object,
2971 /// [`None`] to ignore
2972 ///
2973 /// # Returns
2974 ///
2975 /// a #GFileAttributeInfoList describing the settable attributes.
2976 /// When you are done with it, release it with
2977 /// g_file_attribute_info_list_unref()
2978 #[doc(alias = "g_file_query_settable_attributes")]
2979 fn query_settable_attributes(
2980 &self,
2981 cancellable: Option<&impl IsA<Cancellable>>,
2982 ) -> Result<FileAttributeInfoList, glib::Error> {
2983 unsafe {
2984 let mut error = std::ptr::null_mut();
2985 let ret = ffi::g_file_query_settable_attributes(
2986 self.as_ref().to_glib_none().0,
2987 cancellable.map(|p| p.as_ref()).to_glib_none().0,
2988 &mut error,
2989 );
2990 if error.is_null() {
2991 Ok(from_glib_full(ret))
2992 } else {
2993 Err(from_glib_full(error))
2994 }
2995 }
2996 }
2997
2998 /// Obtain the list of attribute namespaces where new attributes
2999 /// can be created by a user. An example of this is extended
3000 /// attributes (in the "xattr" namespace).
3001 ///
3002 /// If @cancellable is not [`None`], then the operation can be cancelled by
3003 /// triggering the cancellable object from another thread. If the operation
3004 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3005 /// ## `cancellable`
3006 /// optional #GCancellable object,
3007 /// [`None`] to ignore
3008 ///
3009 /// # Returns
3010 ///
3011 /// a #GFileAttributeInfoList describing the writable namespaces.
3012 /// When you are done with it, release it with
3013 /// g_file_attribute_info_list_unref()
3014 #[doc(alias = "g_file_query_writable_namespaces")]
3015 fn query_writable_namespaces(
3016 &self,
3017 cancellable: Option<&impl IsA<Cancellable>>,
3018 ) -> Result<FileAttributeInfoList, glib::Error> {
3019 unsafe {
3020 let mut error = std::ptr::null_mut();
3021 let ret = ffi::g_file_query_writable_namespaces(
3022 self.as_ref().to_glib_none().0,
3023 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3024 &mut error,
3025 );
3026 if error.is_null() {
3027 Ok(from_glib_full(ret))
3028 } else {
3029 Err(from_glib_full(error))
3030 }
3031 }
3032 }
3033
3034 /// Opens a file for reading. The result is a #GFileInputStream that
3035 /// can be used to read the contents of the file.
3036 ///
3037 /// If @cancellable is not [`None`], then the operation can be cancelled by
3038 /// triggering the cancellable object from another thread. If the operation
3039 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3040 ///
3041 /// If the file does not exist, the [`IOErrorEnum::NotFound`][crate::IOErrorEnum::NotFound] error will be
3042 /// returned. If the file is a directory, the [`IOErrorEnum::IsDirectory`][crate::IOErrorEnum::IsDirectory]
3043 /// error will be returned. Other errors are possible too, and depend
3044 /// on what kind of filesystem the file is on.
3045 /// ## `cancellable`
3046 /// a #GCancellable
3047 ///
3048 /// # Returns
3049 ///
3050 /// #GFileInputStream or [`None`] on error.
3051 /// Free the returned object with g_object_unref().
3052 #[doc(alias = "g_file_read")]
3053 fn read(
3054 &self,
3055 cancellable: Option<&impl IsA<Cancellable>>,
3056 ) -> Result<FileInputStream, glib::Error> {
3057 unsafe {
3058 let mut error = std::ptr::null_mut();
3059 let ret = ffi::g_file_read(
3060 self.as_ref().to_glib_none().0,
3061 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3062 &mut error,
3063 );
3064 if error.is_null() {
3065 Ok(from_glib_full(ret))
3066 } else {
3067 Err(from_glib_full(error))
3068 }
3069 }
3070 }
3071
3072 /// Asynchronously opens @self for reading.
3073 ///
3074 /// For more details, see g_file_read() which is
3075 /// the synchronous version of this call.
3076 ///
3077 /// When the operation is finished, @callback will be called.
3078 /// You can then call g_file_read_finish() to get the result
3079 /// of the operation.
3080 /// ## `io_priority`
3081 /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
3082 /// ## `cancellable`
3083 /// optional #GCancellable object,
3084 /// [`None`] to ignore
3085 /// ## `callback`
3086 /// a #GAsyncReadyCallback
3087 /// to call when the request is satisfied
3088 #[doc(alias = "g_file_read_async")]
3089 fn read_async<P: FnOnce(Result<FileInputStream, glib::Error>) + 'static>(
3090 &self,
3091 io_priority: glib::Priority,
3092 cancellable: Option<&impl IsA<Cancellable>>,
3093 callback: P,
3094 ) {
3095 let main_context = glib::MainContext::ref_thread_default();
3096 let is_main_context_owner = main_context.is_owner();
3097 let has_acquired_main_context = (!is_main_context_owner)
3098 .then(|| main_context.acquire().ok())
3099 .flatten();
3100 assert!(
3101 is_main_context_owner || has_acquired_main_context.is_some(),
3102 "Async operations only allowed if the thread is owning the MainContext"
3103 );
3104
3105 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
3106 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
3107 unsafe extern "C" fn read_async_trampoline<
3108 P: FnOnce(Result<FileInputStream, glib::Error>) + 'static,
3109 >(
3110 _source_object: *mut glib::gobject_ffi::GObject,
3111 res: *mut crate::ffi::GAsyncResult,
3112 user_data: glib::ffi::gpointer,
3113 ) {
3114 let mut error = std::ptr::null_mut();
3115 let ret = ffi::g_file_read_finish(_source_object as *mut _, res, &mut error);
3116 let result = if error.is_null() {
3117 Ok(from_glib_full(ret))
3118 } else {
3119 Err(from_glib_full(error))
3120 };
3121 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
3122 Box_::from_raw(user_data as *mut _);
3123 let callback: P = callback.into_inner();
3124 callback(result);
3125 }
3126 let callback = read_async_trampoline::<P>;
3127 unsafe {
3128 ffi::g_file_read_async(
3129 self.as_ref().to_glib_none().0,
3130 io_priority.into_glib(),
3131 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3132 Some(callback),
3133 Box_::into_raw(user_data) as *mut _,
3134 );
3135 }
3136 }
3137
3138 fn read_future(
3139 &self,
3140 io_priority: glib::Priority,
3141 ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileInputStream, glib::Error>> + 'static>>
3142 {
3143 Box_::pin(crate::GioFuture::new(
3144 self,
3145 move |obj, cancellable, send| {
3146 obj.read_async(io_priority, Some(cancellable), move |res| {
3147 send.resolve(res);
3148 });
3149 },
3150 ))
3151 }
3152
3153 /// Returns an output stream for overwriting the file, possibly
3154 /// creating a backup copy of the file first. If the file doesn't exist,
3155 /// it will be created.
3156 ///
3157 /// This will try to replace the file in the safest way possible so
3158 /// that any errors during the writing will not affect an already
3159 /// existing copy of the file. For instance, for local files it
3160 /// may write to a temporary file and then atomically rename over
3161 /// the destination when the stream is closed.
3162 ///
3163 /// By default files created are generally readable by everyone,
3164 /// but if you pass [`FileCreateFlags::PRIVATE`][crate::FileCreateFlags::PRIVATE] in @flags the file
3165 /// will be made readable only to the current user, to the level that
3166 /// is supported on the target filesystem.
3167 ///
3168 /// If @cancellable is not [`None`], then the operation can be cancelled
3169 /// by triggering the cancellable object from another thread. If the
3170 /// operation was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be
3171 /// returned.
3172 ///
3173 /// If you pass in a non-[`None`] @etag value and @self already exists, then
3174 /// this value is compared to the current entity tag of the file, and if
3175 /// they differ an [`IOErrorEnum::WrongEtag`][crate::IOErrorEnum::WrongEtag] error is returned. This
3176 /// generally means that the file has been changed since you last read
3177 /// it. You can get the new etag from g_file_output_stream_get_etag()
3178 /// after you've finished writing and closed the #GFileOutputStream. When
3179 /// you load a new file you can use g_file_input_stream_query_info() to
3180 /// get the etag of the file.
3181 ///
3182 /// If @make_backup is [`true`], this function will attempt to make a
3183 /// backup of the current file before overwriting it. If this fails
3184 /// a [`IOErrorEnum::CantCreateBackup`][crate::IOErrorEnum::CantCreateBackup] error will be returned. If you
3185 /// want to replace anyway, try again with @make_backup set to [`false`].
3186 ///
3187 /// If the file is a directory the [`IOErrorEnum::IsDirectory`][crate::IOErrorEnum::IsDirectory] error will
3188 /// be returned, and if the file is some other form of non-regular file
3189 /// then a [`IOErrorEnum::NotRegularFile`][crate::IOErrorEnum::NotRegularFile] error will be returned. Some
3190 /// file systems don't allow all file names, and may return an
3191 /// [`IOErrorEnum::InvalidFilename`][crate::IOErrorEnum::InvalidFilename] error, and if the name is to long
3192 /// [`IOErrorEnum::FilenameTooLong`][crate::IOErrorEnum::FilenameTooLong] will be returned. Other errors are
3193 /// possible too, and depend on what kind of filesystem the file is on.
3194 /// ## `etag`
3195 /// an optional [entity tag](#entity-tags)
3196 /// for the current #GFile, or #NULL to ignore
3197 /// ## `make_backup`
3198 /// [`true`] if a backup should be created
3199 /// ## `flags`
3200 /// a set of #GFileCreateFlags
3201 /// ## `cancellable`
3202 /// optional #GCancellable object,
3203 /// [`None`] to ignore
3204 ///
3205 /// # Returns
3206 ///
3207 /// a #GFileOutputStream or [`None`] on error.
3208 /// Free the returned object with g_object_unref().
3209 #[doc(alias = "g_file_replace")]
3210 fn replace(
3211 &self,
3212 etag: Option<&str>,
3213 make_backup: bool,
3214 flags: FileCreateFlags,
3215 cancellable: Option<&impl IsA<Cancellable>>,
3216 ) -> Result<FileOutputStream, glib::Error> {
3217 unsafe {
3218 let mut error = std::ptr::null_mut();
3219 let ret = ffi::g_file_replace(
3220 self.as_ref().to_glib_none().0,
3221 etag.to_glib_none().0,
3222 make_backup.into_glib(),
3223 flags.into_glib(),
3224 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3225 &mut error,
3226 );
3227 if error.is_null() {
3228 Ok(from_glib_full(ret))
3229 } else {
3230 Err(from_glib_full(error))
3231 }
3232 }
3233 }
3234
3235 /// Asynchronously overwrites the file, replacing the contents,
3236 /// possibly creating a backup copy of the file first.
3237 ///
3238 /// For more details, see g_file_replace() which is
3239 /// the synchronous version of this call.
3240 ///
3241 /// When the operation is finished, @callback will be called.
3242 /// You can then call g_file_replace_finish() to get the result
3243 /// of the operation.
3244 /// ## `etag`
3245 /// an [entity tag](#entity-tags) for the current #GFile,
3246 /// or [`None`] to ignore
3247 /// ## `make_backup`
3248 /// [`true`] if a backup should be created
3249 /// ## `flags`
3250 /// a set of #GFileCreateFlags
3251 /// ## `io_priority`
3252 /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
3253 /// ## `cancellable`
3254 /// optional #GCancellable object,
3255 /// [`None`] to ignore
3256 /// ## `callback`
3257 /// a #GAsyncReadyCallback
3258 /// to call when the request is satisfied
3259 #[doc(alias = "g_file_replace_async")]
3260 fn replace_async<P: FnOnce(Result<FileOutputStream, glib::Error>) + 'static>(
3261 &self,
3262 etag: Option<&str>,
3263 make_backup: bool,
3264 flags: FileCreateFlags,
3265 io_priority: glib::Priority,
3266 cancellable: Option<&impl IsA<Cancellable>>,
3267 callback: P,
3268 ) {
3269 let main_context = glib::MainContext::ref_thread_default();
3270 let is_main_context_owner = main_context.is_owner();
3271 let has_acquired_main_context = (!is_main_context_owner)
3272 .then(|| main_context.acquire().ok())
3273 .flatten();
3274 assert!(
3275 is_main_context_owner || has_acquired_main_context.is_some(),
3276 "Async operations only allowed if the thread is owning the MainContext"
3277 );
3278
3279 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
3280 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
3281 unsafe extern "C" fn replace_async_trampoline<
3282 P: FnOnce(Result<FileOutputStream, glib::Error>) + 'static,
3283 >(
3284 _source_object: *mut glib::gobject_ffi::GObject,
3285 res: *mut crate::ffi::GAsyncResult,
3286 user_data: glib::ffi::gpointer,
3287 ) {
3288 let mut error = std::ptr::null_mut();
3289 let ret = ffi::g_file_replace_finish(_source_object as *mut _, res, &mut error);
3290 let result = if error.is_null() {
3291 Ok(from_glib_full(ret))
3292 } else {
3293 Err(from_glib_full(error))
3294 };
3295 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
3296 Box_::from_raw(user_data as *mut _);
3297 let callback: P = callback.into_inner();
3298 callback(result);
3299 }
3300 let callback = replace_async_trampoline::<P>;
3301 unsafe {
3302 ffi::g_file_replace_async(
3303 self.as_ref().to_glib_none().0,
3304 etag.to_glib_none().0,
3305 make_backup.into_glib(),
3306 flags.into_glib(),
3307 io_priority.into_glib(),
3308 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3309 Some(callback),
3310 Box_::into_raw(user_data) as *mut _,
3311 );
3312 }
3313 }
3314
3315 fn replace_future(
3316 &self,
3317 etag: Option<&str>,
3318 make_backup: bool,
3319 flags: FileCreateFlags,
3320 io_priority: glib::Priority,
3321 ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileOutputStream, glib::Error>> + 'static>>
3322 {
3323 let etag = etag.map(ToOwned::to_owned);
3324 Box_::pin(crate::GioFuture::new(
3325 self,
3326 move |obj, cancellable, send| {
3327 obj.replace_async(
3328 etag.as_ref().map(::std::borrow::Borrow::borrow),
3329 make_backup,
3330 flags,
3331 io_priority,
3332 Some(cancellable),
3333 move |res| {
3334 send.resolve(res);
3335 },
3336 );
3337 },
3338 ))
3339 }
3340
3341 /// Replaces the contents of @self with @contents of @length bytes.
3342 ///
3343 /// If @etag is specified (not [`None`]), any existing file must have that etag,
3344 /// or the error [`IOErrorEnum::WrongEtag`][crate::IOErrorEnum::WrongEtag] will be returned.
3345 ///
3346 /// If @make_backup is [`true`], this function will attempt to make a backup
3347 /// of @self. Internally, it uses g_file_replace(), so will try to replace the
3348 /// file contents in the safest way possible. For example, atomic renames are
3349 /// used when replacing local files’ contents.
3350 ///
3351 /// If @cancellable is not [`None`], then the operation can be cancelled by
3352 /// triggering the cancellable object from another thread. If the operation
3353 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3354 ///
3355 /// The returned @new_etag can be used to verify that the file hasn't
3356 /// changed the next time it is saved over.
3357 /// ## `contents`
3358 /// a string containing the new contents for @self
3359 /// ## `etag`
3360 /// the old [entity-tag](#entity-tags) for the document,
3361 /// or [`None`]
3362 /// ## `make_backup`
3363 /// [`true`] if a backup should be created
3364 /// ## `flags`
3365 /// a set of #GFileCreateFlags
3366 /// ## `cancellable`
3367 /// optional #GCancellable object, [`None`] to ignore
3368 ///
3369 /// # Returns
3370 ///
3371 /// [`true`] if successful. If an error has occurred, this function
3372 /// will return [`false`] and set @error appropriately if present.
3373 ///
3374 /// ## `new_etag`
3375 /// a location to a new [entity tag](#entity-tags)
3376 /// for the document. This should be freed with g_free() when no longer
3377 /// needed, or [`None`]
3378 #[doc(alias = "g_file_replace_contents")]
3379 fn replace_contents(
3380 &self,
3381 contents: &[u8],
3382 etag: Option<&str>,
3383 make_backup: bool,
3384 flags: FileCreateFlags,
3385 cancellable: Option<&impl IsA<Cancellable>>,
3386 ) -> Result<Option<glib::GString>, glib::Error> {
3387 let length = contents.len() as _;
3388 unsafe {
3389 let mut new_etag = std::ptr::null_mut();
3390 let mut error = std::ptr::null_mut();
3391 let is_ok = ffi::g_file_replace_contents(
3392 self.as_ref().to_glib_none().0,
3393 contents.to_glib_none().0,
3394 length,
3395 etag.to_glib_none().0,
3396 make_backup.into_glib(),
3397 flags.into_glib(),
3398 &mut new_etag,
3399 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3400 &mut error,
3401 );
3402 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
3403 if error.is_null() {
3404 Ok(from_glib_full(new_etag))
3405 } else {
3406 Err(from_glib_full(error))
3407 }
3408 }
3409 }
3410
3411 //#[doc(alias = "g_file_replace_contents_bytes_async")]
3412 //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) {
3413 // unsafe { TODO: call ffi:g_file_replace_contents_bytes_async() }
3414 //}
3415
3416 /// Returns an output stream for overwriting the file in readwrite mode,
3417 /// possibly creating a backup copy of the file first. If the file doesn't
3418 /// exist, it will be created.
3419 ///
3420 /// For details about the behaviour, see g_file_replace() which does the
3421 /// same thing but returns an output stream only.
3422 ///
3423 /// Note that in many non-local file cases read and write streams are not
3424 /// supported, so make sure you really need to do read and write streaming,
3425 /// rather than just opening for reading or writing.
3426 /// ## `etag`
3427 /// an optional [entity tag](#entity-tags)
3428 /// for the current #GFile, or #NULL to ignore
3429 /// ## `make_backup`
3430 /// [`true`] if a backup should be created
3431 /// ## `flags`
3432 /// a set of #GFileCreateFlags
3433 /// ## `cancellable`
3434 /// optional #GCancellable object,
3435 /// [`None`] to ignore
3436 ///
3437 /// # Returns
3438 ///
3439 /// a #GFileIOStream or [`None`] on error.
3440 /// Free the returned object with g_object_unref().
3441 #[doc(alias = "g_file_replace_readwrite")]
3442 fn replace_readwrite(
3443 &self,
3444 etag: Option<&str>,
3445 make_backup: bool,
3446 flags: FileCreateFlags,
3447 cancellable: Option<&impl IsA<Cancellable>>,
3448 ) -> Result<FileIOStream, glib::Error> {
3449 unsafe {
3450 let mut error = std::ptr::null_mut();
3451 let ret = ffi::g_file_replace_readwrite(
3452 self.as_ref().to_glib_none().0,
3453 etag.to_glib_none().0,
3454 make_backup.into_glib(),
3455 flags.into_glib(),
3456 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3457 &mut error,
3458 );
3459 if error.is_null() {
3460 Ok(from_glib_full(ret))
3461 } else {
3462 Err(from_glib_full(error))
3463 }
3464 }
3465 }
3466
3467 /// Asynchronously overwrites the file in read-write mode,
3468 /// replacing the contents, possibly creating a backup copy
3469 /// of the file first.
3470 ///
3471 /// For more details, see g_file_replace_readwrite() which is
3472 /// the synchronous version of this call.
3473 ///
3474 /// When the operation is finished, @callback will be called.
3475 /// You can then call g_file_replace_readwrite_finish() to get
3476 /// the result of the operation.
3477 /// ## `etag`
3478 /// an [entity tag](#entity-tags) for the current #GFile,
3479 /// or [`None`] to ignore
3480 /// ## `make_backup`
3481 /// [`true`] if a backup should be created
3482 /// ## `flags`
3483 /// a set of #GFileCreateFlags
3484 /// ## `io_priority`
3485 /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
3486 /// ## `cancellable`
3487 /// optional #GCancellable object,
3488 /// [`None`] to ignore
3489 /// ## `callback`
3490 /// a #GAsyncReadyCallback
3491 /// to call when the request is satisfied
3492 #[doc(alias = "g_file_replace_readwrite_async")]
3493 fn replace_readwrite_async<P: FnOnce(Result<FileIOStream, glib::Error>) + 'static>(
3494 &self,
3495 etag: Option<&str>,
3496 make_backup: bool,
3497 flags: FileCreateFlags,
3498 io_priority: glib::Priority,
3499 cancellable: Option<&impl IsA<Cancellable>>,
3500 callback: P,
3501 ) {
3502 let main_context = glib::MainContext::ref_thread_default();
3503 let is_main_context_owner = main_context.is_owner();
3504 let has_acquired_main_context = (!is_main_context_owner)
3505 .then(|| main_context.acquire().ok())
3506 .flatten();
3507 assert!(
3508 is_main_context_owner || has_acquired_main_context.is_some(),
3509 "Async operations only allowed if the thread is owning the MainContext"
3510 );
3511
3512 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
3513 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
3514 unsafe extern "C" fn replace_readwrite_async_trampoline<
3515 P: FnOnce(Result<FileIOStream, glib::Error>) + 'static,
3516 >(
3517 _source_object: *mut glib::gobject_ffi::GObject,
3518 res: *mut crate::ffi::GAsyncResult,
3519 user_data: glib::ffi::gpointer,
3520 ) {
3521 let mut error = std::ptr::null_mut();
3522 let ret =
3523 ffi::g_file_replace_readwrite_finish(_source_object as *mut _, res, &mut error);
3524 let result = if error.is_null() {
3525 Ok(from_glib_full(ret))
3526 } else {
3527 Err(from_glib_full(error))
3528 };
3529 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
3530 Box_::from_raw(user_data as *mut _);
3531 let callback: P = callback.into_inner();
3532 callback(result);
3533 }
3534 let callback = replace_readwrite_async_trampoline::<P>;
3535 unsafe {
3536 ffi::g_file_replace_readwrite_async(
3537 self.as_ref().to_glib_none().0,
3538 etag.to_glib_none().0,
3539 make_backup.into_glib(),
3540 flags.into_glib(),
3541 io_priority.into_glib(),
3542 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3543 Some(callback),
3544 Box_::into_raw(user_data) as *mut _,
3545 );
3546 }
3547 }
3548
3549 fn replace_readwrite_future(
3550 &self,
3551 etag: Option<&str>,
3552 make_backup: bool,
3553 flags: FileCreateFlags,
3554 io_priority: glib::Priority,
3555 ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileIOStream, glib::Error>> + 'static>>
3556 {
3557 let etag = etag.map(ToOwned::to_owned);
3558 Box_::pin(crate::GioFuture::new(
3559 self,
3560 move |obj, cancellable, send| {
3561 obj.replace_readwrite_async(
3562 etag.as_ref().map(::std::borrow::Borrow::borrow),
3563 make_backup,
3564 flags,
3565 io_priority,
3566 Some(cancellable),
3567 move |res| {
3568 send.resolve(res);
3569 },
3570 );
3571 },
3572 ))
3573 }
3574
3575 /// Resolves a relative path for @self to an absolute path.
3576 ///
3577 /// This call does no blocking I/O.
3578 ///
3579 /// If the @relative_path is an absolute path name, the resolution
3580 /// is done absolutely (without taking @self path as base).
3581 /// ## `relative_path`
3582 /// a given relative path string
3583 ///
3584 /// # Returns
3585 ///
3586 /// a #GFile for the resolved path.
3587 #[doc(alias = "g_file_resolve_relative_path")]
3588 #[must_use]
3589 fn resolve_relative_path(&self, relative_path: impl AsRef<std::path::Path>) -> File {
3590 unsafe {
3591 from_glib_full(ffi::g_file_resolve_relative_path(
3592 self.as_ref().to_glib_none().0,
3593 relative_path.as_ref().to_glib_none().0,
3594 ))
3595 }
3596 }
3597
3598 //#[doc(alias = "g_file_set_attribute")]
3599 //fn set_attribute(&self, attribute: &str, type_: FileAttributeType, value_p: /*Unimplemented*/Option<Basic: Pointer>, flags: FileQueryInfoFlags, cancellable: Option<&impl IsA<Cancellable>>) -> Result<(), glib::Error> {
3600 // unsafe { TODO: call ffi:g_file_set_attribute() }
3601 //}
3602
3603 /// Sets @attribute of type [`FileAttributeType::ByteString`][crate::FileAttributeType::ByteString] to @value.
3604 /// If @attribute is of a different type, this operation will fail,
3605 /// returning [`false`].
3606 ///
3607 /// If @cancellable is not [`None`], then the operation can be cancelled by
3608 /// triggering the cancellable object from another thread. If the operation
3609 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3610 /// ## `attribute`
3611 /// a string containing the attribute's name
3612 /// ## `value`
3613 /// a string containing the attribute's new value
3614 /// ## `flags`
3615 /// a #GFileQueryInfoFlags
3616 /// ## `cancellable`
3617 /// optional #GCancellable object,
3618 /// [`None`] to ignore
3619 ///
3620 /// # Returns
3621 ///
3622 /// [`true`] if the @attribute was successfully set to @value
3623 /// in the @self, [`false`] otherwise.
3624 #[doc(alias = "g_file_set_attribute_byte_string")]
3625 fn set_attribute_byte_string(
3626 &self,
3627 attribute: &str,
3628 value: &str,
3629 flags: FileQueryInfoFlags,
3630 cancellable: Option<&impl IsA<Cancellable>>,
3631 ) -> Result<(), glib::Error> {
3632 unsafe {
3633 let mut error = std::ptr::null_mut();
3634 let is_ok = ffi::g_file_set_attribute_byte_string(
3635 self.as_ref().to_glib_none().0,
3636 attribute.to_glib_none().0,
3637 value.to_glib_none().0,
3638 flags.into_glib(),
3639 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3640 &mut error,
3641 );
3642 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
3643 if error.is_null() {
3644 Ok(())
3645 } else {
3646 Err(from_glib_full(error))
3647 }
3648 }
3649 }
3650
3651 /// Sets @attribute of type [`FileAttributeType::Int32`][crate::FileAttributeType::Int32] to @value.
3652 /// If @attribute is of a different type, this operation will fail.
3653 ///
3654 /// If @cancellable is not [`None`], then the operation can be cancelled by
3655 /// triggering the cancellable object from another thread. If the operation
3656 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3657 /// ## `attribute`
3658 /// a string containing the attribute's name
3659 /// ## `value`
3660 /// a #gint32 containing the attribute's new value
3661 /// ## `flags`
3662 /// a #GFileQueryInfoFlags
3663 /// ## `cancellable`
3664 /// optional #GCancellable object,
3665 /// [`None`] to ignore
3666 ///
3667 /// # Returns
3668 ///
3669 /// [`true`] if the @attribute was successfully set to @value
3670 /// in the @self, [`false`] otherwise.
3671 #[doc(alias = "g_file_set_attribute_int32")]
3672 fn set_attribute_int32(
3673 &self,
3674 attribute: &str,
3675 value: i32,
3676 flags: FileQueryInfoFlags,
3677 cancellable: Option<&impl IsA<Cancellable>>,
3678 ) -> Result<(), glib::Error> {
3679 unsafe {
3680 let mut error = std::ptr::null_mut();
3681 let is_ok = ffi::g_file_set_attribute_int32(
3682 self.as_ref().to_glib_none().0,
3683 attribute.to_glib_none().0,
3684 value,
3685 flags.into_glib(),
3686 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3687 &mut error,
3688 );
3689 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
3690 if error.is_null() {
3691 Ok(())
3692 } else {
3693 Err(from_glib_full(error))
3694 }
3695 }
3696 }
3697
3698 /// Sets @attribute of type [`FileAttributeType::Int64`][crate::FileAttributeType::Int64] to @value.
3699 /// If @attribute is of a different type, this operation will fail.
3700 ///
3701 /// If @cancellable is not [`None`], then the operation can be cancelled by
3702 /// triggering the cancellable object from another thread. If the operation
3703 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3704 /// ## `attribute`
3705 /// a string containing the attribute's name
3706 /// ## `value`
3707 /// a #guint64 containing the attribute's new value
3708 /// ## `flags`
3709 /// a #GFileQueryInfoFlags
3710 /// ## `cancellable`
3711 /// optional #GCancellable object,
3712 /// [`None`] to ignore
3713 ///
3714 /// # Returns
3715 ///
3716 /// [`true`] if the @attribute was successfully set, [`false`] otherwise.
3717 #[doc(alias = "g_file_set_attribute_int64")]
3718 fn set_attribute_int64(
3719 &self,
3720 attribute: &str,
3721 value: i64,
3722 flags: FileQueryInfoFlags,
3723 cancellable: Option<&impl IsA<Cancellable>>,
3724 ) -> Result<(), glib::Error> {
3725 unsafe {
3726 let mut error = std::ptr::null_mut();
3727 let is_ok = ffi::g_file_set_attribute_int64(
3728 self.as_ref().to_glib_none().0,
3729 attribute.to_glib_none().0,
3730 value,
3731 flags.into_glib(),
3732 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3733 &mut error,
3734 );
3735 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
3736 if error.is_null() {
3737 Ok(())
3738 } else {
3739 Err(from_glib_full(error))
3740 }
3741 }
3742 }
3743
3744 /// Sets @attribute of type [`FileAttributeType::String`][crate::FileAttributeType::String] to @value.
3745 /// If @attribute is of a different type, this operation will fail.
3746 ///
3747 /// If @cancellable is not [`None`], then the operation can be cancelled by
3748 /// triggering the cancellable object from another thread. If the operation
3749 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3750 /// ## `attribute`
3751 /// a string containing the attribute's name
3752 /// ## `value`
3753 /// a string containing the attribute's value
3754 /// ## `flags`
3755 /// #GFileQueryInfoFlags
3756 /// ## `cancellable`
3757 /// optional #GCancellable object,
3758 /// [`None`] to ignore
3759 ///
3760 /// # Returns
3761 ///
3762 /// [`true`] if the @attribute was successfully set, [`false`] otherwise.
3763 #[doc(alias = "g_file_set_attribute_string")]
3764 fn set_attribute_string(
3765 &self,
3766 attribute: &str,
3767 value: &str,
3768 flags: FileQueryInfoFlags,
3769 cancellable: Option<&impl IsA<Cancellable>>,
3770 ) -> Result<(), glib::Error> {
3771 unsafe {
3772 let mut error = std::ptr::null_mut();
3773 let is_ok = ffi::g_file_set_attribute_string(
3774 self.as_ref().to_glib_none().0,
3775 attribute.to_glib_none().0,
3776 value.to_glib_none().0,
3777 flags.into_glib(),
3778 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3779 &mut error,
3780 );
3781 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
3782 if error.is_null() {
3783 Ok(())
3784 } else {
3785 Err(from_glib_full(error))
3786 }
3787 }
3788 }
3789
3790 /// Sets @attribute of type [`FileAttributeType::Uint32`][crate::FileAttributeType::Uint32] to @value.
3791 /// If @attribute is of a different type, this operation will fail.
3792 ///
3793 /// If @cancellable is not [`None`], then the operation can be cancelled by
3794 /// triggering the cancellable object from another thread. If the operation
3795 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3796 /// ## `attribute`
3797 /// a string containing the attribute's name
3798 /// ## `value`
3799 /// a #guint32 containing the attribute's new value
3800 /// ## `flags`
3801 /// a #GFileQueryInfoFlags
3802 /// ## `cancellable`
3803 /// optional #GCancellable object,
3804 /// [`None`] to ignore
3805 ///
3806 /// # Returns
3807 ///
3808 /// [`true`] if the @attribute was successfully set to @value
3809 /// in the @self, [`false`] otherwise.
3810 #[doc(alias = "g_file_set_attribute_uint32")]
3811 fn set_attribute_uint32(
3812 &self,
3813 attribute: &str,
3814 value: u32,
3815 flags: FileQueryInfoFlags,
3816 cancellable: Option<&impl IsA<Cancellable>>,
3817 ) -> Result<(), glib::Error> {
3818 unsafe {
3819 let mut error = std::ptr::null_mut();
3820 let is_ok = ffi::g_file_set_attribute_uint32(
3821 self.as_ref().to_glib_none().0,
3822 attribute.to_glib_none().0,
3823 value,
3824 flags.into_glib(),
3825 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3826 &mut error,
3827 );
3828 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
3829 if error.is_null() {
3830 Ok(())
3831 } else {
3832 Err(from_glib_full(error))
3833 }
3834 }
3835 }
3836
3837 /// Sets @attribute of type [`FileAttributeType::Uint64`][crate::FileAttributeType::Uint64] to @value.
3838 /// If @attribute is of a different type, this operation will fail.
3839 ///
3840 /// If @cancellable is not [`None`], then the operation can be cancelled by
3841 /// triggering the cancellable object from another thread. If the operation
3842 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3843 /// ## `attribute`
3844 /// a string containing the attribute's name
3845 /// ## `value`
3846 /// a #guint64 containing the attribute's new value
3847 /// ## `flags`
3848 /// a #GFileQueryInfoFlags
3849 /// ## `cancellable`
3850 /// optional #GCancellable object,
3851 /// [`None`] to ignore
3852 ///
3853 /// # Returns
3854 ///
3855 /// [`true`] if the @attribute was successfully set to @value
3856 /// in the @self, [`false`] otherwise.
3857 #[doc(alias = "g_file_set_attribute_uint64")]
3858 fn set_attribute_uint64(
3859 &self,
3860 attribute: &str,
3861 value: u64,
3862 flags: FileQueryInfoFlags,
3863 cancellable: Option<&impl IsA<Cancellable>>,
3864 ) -> Result<(), glib::Error> {
3865 unsafe {
3866 let mut error = std::ptr::null_mut();
3867 let is_ok = ffi::g_file_set_attribute_uint64(
3868 self.as_ref().to_glib_none().0,
3869 attribute.to_glib_none().0,
3870 value,
3871 flags.into_glib(),
3872 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3873 &mut error,
3874 );
3875 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
3876 if error.is_null() {
3877 Ok(())
3878 } else {
3879 Err(from_glib_full(error))
3880 }
3881 }
3882 }
3883
3884 /// Asynchronously sets the attributes of @self with @info.
3885 ///
3886 /// For more details, see g_file_set_attributes_from_info(),
3887 /// which is the synchronous version of this call.
3888 ///
3889 /// When the operation is finished, @callback will be called.
3890 /// You can then call g_file_set_attributes_finish() to get
3891 /// the result of the operation.
3892 /// ## `info`
3893 /// a #GFileInfo
3894 /// ## `flags`
3895 /// a #GFileQueryInfoFlags
3896 /// ## `io_priority`
3897 /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
3898 /// ## `cancellable`
3899 /// optional #GCancellable object,
3900 /// [`None`] to ignore
3901 /// ## `callback`
3902 /// a #GAsyncReadyCallback
3903 /// to call when the request is satisfied
3904 #[doc(alias = "g_file_set_attributes_async")]
3905 fn set_attributes_async<P: FnOnce(Result<FileInfo, glib::Error>) + 'static>(
3906 &self,
3907 info: &FileInfo,
3908 flags: FileQueryInfoFlags,
3909 io_priority: glib::Priority,
3910 cancellable: Option<&impl IsA<Cancellable>>,
3911 callback: P,
3912 ) {
3913 let main_context = glib::MainContext::ref_thread_default();
3914 let is_main_context_owner = main_context.is_owner();
3915 let has_acquired_main_context = (!is_main_context_owner)
3916 .then(|| main_context.acquire().ok())
3917 .flatten();
3918 assert!(
3919 is_main_context_owner || has_acquired_main_context.is_some(),
3920 "Async operations only allowed if the thread is owning the MainContext"
3921 );
3922
3923 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
3924 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
3925 unsafe extern "C" fn set_attributes_async_trampoline<
3926 P: FnOnce(Result<FileInfo, glib::Error>) + 'static,
3927 >(
3928 _source_object: *mut glib::gobject_ffi::GObject,
3929 res: *mut crate::ffi::GAsyncResult,
3930 user_data: glib::ffi::gpointer,
3931 ) {
3932 let mut error = std::ptr::null_mut();
3933 let mut info = std::ptr::null_mut();
3934 ffi::g_file_set_attributes_finish(_source_object as *mut _, res, &mut info, &mut error);
3935 let result = if error.is_null() {
3936 Ok(from_glib_full(info))
3937 } else {
3938 Err(from_glib_full(error))
3939 };
3940 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
3941 Box_::from_raw(user_data as *mut _);
3942 let callback: P = callback.into_inner();
3943 callback(result);
3944 }
3945 let callback = set_attributes_async_trampoline::<P>;
3946 unsafe {
3947 ffi::g_file_set_attributes_async(
3948 self.as_ref().to_glib_none().0,
3949 info.to_glib_none().0,
3950 flags.into_glib(),
3951 io_priority.into_glib(),
3952 cancellable.map(|p| p.as_ref()).to_glib_none().0,
3953 Some(callback),
3954 Box_::into_raw(user_data) as *mut _,
3955 );
3956 }
3957 }
3958
3959 fn set_attributes_future(
3960 &self,
3961 info: &FileInfo,
3962 flags: FileQueryInfoFlags,
3963 io_priority: glib::Priority,
3964 ) -> Pin<Box_<dyn std::future::Future<Output = Result<FileInfo, glib::Error>> + 'static>> {
3965 let info = info.clone();
3966 Box_::pin(crate::GioFuture::new(
3967 self,
3968 move |obj, cancellable, send| {
3969 obj.set_attributes_async(
3970 &info,
3971 flags,
3972 io_priority,
3973 Some(cancellable),
3974 move |res| {
3975 send.resolve(res);
3976 },
3977 );
3978 },
3979 ))
3980 }
3981
3982 /// Tries to set all attributes in the #GFileInfo on the target
3983 /// values, not stopping on the first error.
3984 ///
3985 /// If there is any error during this operation then @error will
3986 /// be set to the first error. Error on particular fields are flagged
3987 /// by setting the "status" field in the attribute value to
3988 /// [`FileAttributeStatus::ErrorSetting`][crate::FileAttributeStatus::ErrorSetting], which means you can
3989 /// also detect further errors.
3990 ///
3991 /// If @cancellable is not [`None`], then the operation can be cancelled by
3992 /// triggering the cancellable object from another thread. If the operation
3993 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
3994 /// ## `info`
3995 /// a #GFileInfo
3996 /// ## `flags`
3997 /// #GFileQueryInfoFlags
3998 /// ## `cancellable`
3999 /// optional #GCancellable object,
4000 /// [`None`] to ignore
4001 ///
4002 /// # Returns
4003 ///
4004 /// [`false`] if there was any error, [`true`] otherwise.
4005 #[doc(alias = "g_file_set_attributes_from_info")]
4006 fn set_attributes_from_info(
4007 &self,
4008 info: &FileInfo,
4009 flags: FileQueryInfoFlags,
4010 cancellable: Option<&impl IsA<Cancellable>>,
4011 ) -> Result<(), glib::Error> {
4012 unsafe {
4013 let mut error = std::ptr::null_mut();
4014 let is_ok = ffi::g_file_set_attributes_from_info(
4015 self.as_ref().to_glib_none().0,
4016 info.to_glib_none().0,
4017 flags.into_glib(),
4018 cancellable.map(|p| p.as_ref()).to_glib_none().0,
4019 &mut error,
4020 );
4021 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
4022 if error.is_null() {
4023 Ok(())
4024 } else {
4025 Err(from_glib_full(error))
4026 }
4027 }
4028 }
4029
4030 /// Renames @self to the specified display name.
4031 ///
4032 /// The display name is converted from UTF-8 to the correct encoding
4033 /// for the target filesystem if possible and the @self is renamed to this.
4034 ///
4035 /// If you want to implement a rename operation in the user interface the
4036 /// edit name ([`FILE_ATTRIBUTE_STANDARD_EDIT_NAME`][crate::FILE_ATTRIBUTE_STANDARD_EDIT_NAME]) should be used as the
4037 /// initial value in the rename widget, and then the result after editing
4038 /// should be passed to g_file_set_display_name().
4039 ///
4040 /// On success the resulting converted filename is returned.
4041 ///
4042 /// If @cancellable is not [`None`], then the operation can be cancelled by
4043 /// triggering the cancellable object from another thread. If the operation
4044 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4045 /// ## `display_name`
4046 /// a string
4047 /// ## `cancellable`
4048 /// optional #GCancellable object,
4049 /// [`None`] to ignore
4050 ///
4051 /// # Returns
4052 ///
4053 /// a #GFile specifying what @self was renamed to,
4054 /// or [`None`] if there was an error.
4055 /// Free the returned object with g_object_unref().
4056 #[doc(alias = "g_file_set_display_name")]
4057 fn set_display_name(
4058 &self,
4059 display_name: &str,
4060 cancellable: Option<&impl IsA<Cancellable>>,
4061 ) -> Result<File, glib::Error> {
4062 unsafe {
4063 let mut error = std::ptr::null_mut();
4064 let ret = ffi::g_file_set_display_name(
4065 self.as_ref().to_glib_none().0,
4066 display_name.to_glib_none().0,
4067 cancellable.map(|p| p.as_ref()).to_glib_none().0,
4068 &mut error,
4069 );
4070 if error.is_null() {
4071 Ok(from_glib_full(ret))
4072 } else {
4073 Err(from_glib_full(error))
4074 }
4075 }
4076 }
4077
4078 /// Asynchronously sets the display name for a given #GFile.
4079 ///
4080 /// For more details, see g_file_set_display_name() which is
4081 /// the synchronous version of this call.
4082 ///
4083 /// When the operation is finished, @callback will be called.
4084 /// You can then call g_file_set_display_name_finish() to get
4085 /// the result of the operation.
4086 /// ## `display_name`
4087 /// a string
4088 /// ## `io_priority`
4089 /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
4090 /// ## `cancellable`
4091 /// optional #GCancellable object,
4092 /// [`None`] to ignore
4093 /// ## `callback`
4094 /// a #GAsyncReadyCallback
4095 /// to call when the request is satisfied
4096 #[doc(alias = "g_file_set_display_name_async")]
4097 fn set_display_name_async<P: FnOnce(Result<File, glib::Error>) + 'static>(
4098 &self,
4099 display_name: &str,
4100 io_priority: glib::Priority,
4101 cancellable: Option<&impl IsA<Cancellable>>,
4102 callback: P,
4103 ) {
4104 let main_context = glib::MainContext::ref_thread_default();
4105 let is_main_context_owner = main_context.is_owner();
4106 let has_acquired_main_context = (!is_main_context_owner)
4107 .then(|| main_context.acquire().ok())
4108 .flatten();
4109 assert!(
4110 is_main_context_owner || has_acquired_main_context.is_some(),
4111 "Async operations only allowed if the thread is owning the MainContext"
4112 );
4113
4114 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
4115 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
4116 unsafe extern "C" fn set_display_name_async_trampoline<
4117 P: FnOnce(Result<File, glib::Error>) + 'static,
4118 >(
4119 _source_object: *mut glib::gobject_ffi::GObject,
4120 res: *mut crate::ffi::GAsyncResult,
4121 user_data: glib::ffi::gpointer,
4122 ) {
4123 let mut error = std::ptr::null_mut();
4124 let ret =
4125 ffi::g_file_set_display_name_finish(_source_object as *mut _, res, &mut error);
4126 let result = if error.is_null() {
4127 Ok(from_glib_full(ret))
4128 } else {
4129 Err(from_glib_full(error))
4130 };
4131 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
4132 Box_::from_raw(user_data as *mut _);
4133 let callback: P = callback.into_inner();
4134 callback(result);
4135 }
4136 let callback = set_display_name_async_trampoline::<P>;
4137 unsafe {
4138 ffi::g_file_set_display_name_async(
4139 self.as_ref().to_glib_none().0,
4140 display_name.to_glib_none().0,
4141 io_priority.into_glib(),
4142 cancellable.map(|p| p.as_ref()).to_glib_none().0,
4143 Some(callback),
4144 Box_::into_raw(user_data) as *mut _,
4145 );
4146 }
4147 }
4148
4149 fn set_display_name_future(
4150 &self,
4151 display_name: &str,
4152 io_priority: glib::Priority,
4153 ) -> Pin<Box_<dyn std::future::Future<Output = Result<File, glib::Error>> + 'static>> {
4154 let display_name = String::from(display_name);
4155 Box_::pin(crate::GioFuture::new(
4156 self,
4157 move |obj, cancellable, send| {
4158 obj.set_display_name_async(
4159 &display_name,
4160 io_priority,
4161 Some(cancellable),
4162 move |res| {
4163 send.resolve(res);
4164 },
4165 );
4166 },
4167 ))
4168 }
4169
4170 /// Starts a file of type [`FileType::Mountable`][crate::FileType::Mountable].
4171 /// Using @start_operation, you can request callbacks when, for instance,
4172 /// passwords are needed during authentication.
4173 ///
4174 /// If @cancellable is not [`None`], then the operation can be cancelled by
4175 /// triggering the cancellable object from another thread. If the operation
4176 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4177 ///
4178 /// When the operation is finished, @callback will be called.
4179 /// You can then call g_file_mount_mountable_finish() to get
4180 /// the result of the operation.
4181 /// ## `flags`
4182 /// flags affecting the operation
4183 /// ## `start_operation`
4184 /// a #GMountOperation, or [`None`] to avoid user interaction
4185 /// ## `cancellable`
4186 /// optional #GCancellable object, [`None`] to ignore
4187 /// ## `callback`
4188 /// a #GAsyncReadyCallback to call when the request is satisfied, or [`None`]
4189 #[doc(alias = "g_file_start_mountable")]
4190 fn start_mountable<P: FnOnce(Result<(), glib::Error>) + 'static>(
4191 &self,
4192 flags: DriveStartFlags,
4193 start_operation: Option<&impl IsA<MountOperation>>,
4194 cancellable: Option<&impl IsA<Cancellable>>,
4195 callback: P,
4196 ) {
4197 let main_context = glib::MainContext::ref_thread_default();
4198 let is_main_context_owner = main_context.is_owner();
4199 let has_acquired_main_context = (!is_main_context_owner)
4200 .then(|| main_context.acquire().ok())
4201 .flatten();
4202 assert!(
4203 is_main_context_owner || has_acquired_main_context.is_some(),
4204 "Async operations only allowed if the thread is owning the MainContext"
4205 );
4206
4207 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
4208 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
4209 unsafe extern "C" fn start_mountable_trampoline<
4210 P: FnOnce(Result<(), glib::Error>) + 'static,
4211 >(
4212 _source_object: *mut glib::gobject_ffi::GObject,
4213 res: *mut crate::ffi::GAsyncResult,
4214 user_data: glib::ffi::gpointer,
4215 ) {
4216 let mut error = std::ptr::null_mut();
4217 ffi::g_file_start_mountable_finish(_source_object as *mut _, res, &mut error);
4218 let result = if error.is_null() {
4219 Ok(())
4220 } else {
4221 Err(from_glib_full(error))
4222 };
4223 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
4224 Box_::from_raw(user_data as *mut _);
4225 let callback: P = callback.into_inner();
4226 callback(result);
4227 }
4228 let callback = start_mountable_trampoline::<P>;
4229 unsafe {
4230 ffi::g_file_start_mountable(
4231 self.as_ref().to_glib_none().0,
4232 flags.into_glib(),
4233 start_operation.map(|p| p.as_ref()).to_glib_none().0,
4234 cancellable.map(|p| p.as_ref()).to_glib_none().0,
4235 Some(callback),
4236 Box_::into_raw(user_data) as *mut _,
4237 );
4238 }
4239 }
4240
4241 fn start_mountable_future(
4242 &self,
4243 flags: DriveStartFlags,
4244 start_operation: Option<&(impl IsA<MountOperation> + Clone + 'static)>,
4245 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
4246 let start_operation = start_operation.map(ToOwned::to_owned);
4247 Box_::pin(crate::GioFuture::new(
4248 self,
4249 move |obj, cancellable, send| {
4250 obj.start_mountable(
4251 flags,
4252 start_operation.as_ref().map(::std::borrow::Borrow::borrow),
4253 Some(cancellable),
4254 move |res| {
4255 send.resolve(res);
4256 },
4257 );
4258 },
4259 ))
4260 }
4261
4262 /// Stops a file of type [`FileType::Mountable`][crate::FileType::Mountable].
4263 ///
4264 /// If @cancellable is not [`None`], then the operation can be cancelled by
4265 /// triggering the cancellable object from another thread. If the operation
4266 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4267 ///
4268 /// When the operation is finished, @callback will be called.
4269 /// You can then call g_file_stop_mountable_finish() to get
4270 /// the result of the operation.
4271 /// ## `flags`
4272 /// flags affecting the operation
4273 /// ## `mount_operation`
4274 /// a #GMountOperation,
4275 /// or [`None`] to avoid user interaction.
4276 /// ## `cancellable`
4277 /// optional #GCancellable object,
4278 /// [`None`] to ignore
4279 /// ## `callback`
4280 /// a #GAsyncReadyCallback to call
4281 /// when the request is satisfied, or [`None`]
4282 #[doc(alias = "g_file_stop_mountable")]
4283 fn stop_mountable<P: FnOnce(Result<(), glib::Error>) + 'static>(
4284 &self,
4285 flags: MountUnmountFlags,
4286 mount_operation: Option<&impl IsA<MountOperation>>,
4287 cancellable: Option<&impl IsA<Cancellable>>,
4288 callback: P,
4289 ) {
4290 let main_context = glib::MainContext::ref_thread_default();
4291 let is_main_context_owner = main_context.is_owner();
4292 let has_acquired_main_context = (!is_main_context_owner)
4293 .then(|| main_context.acquire().ok())
4294 .flatten();
4295 assert!(
4296 is_main_context_owner || has_acquired_main_context.is_some(),
4297 "Async operations only allowed if the thread is owning the MainContext"
4298 );
4299
4300 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
4301 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
4302 unsafe extern "C" fn stop_mountable_trampoline<
4303 P: FnOnce(Result<(), glib::Error>) + 'static,
4304 >(
4305 _source_object: *mut glib::gobject_ffi::GObject,
4306 res: *mut crate::ffi::GAsyncResult,
4307 user_data: glib::ffi::gpointer,
4308 ) {
4309 let mut error = std::ptr::null_mut();
4310 ffi::g_file_stop_mountable_finish(_source_object as *mut _, res, &mut error);
4311 let result = if error.is_null() {
4312 Ok(())
4313 } else {
4314 Err(from_glib_full(error))
4315 };
4316 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
4317 Box_::from_raw(user_data as *mut _);
4318 let callback: P = callback.into_inner();
4319 callback(result);
4320 }
4321 let callback = stop_mountable_trampoline::<P>;
4322 unsafe {
4323 ffi::g_file_stop_mountable(
4324 self.as_ref().to_glib_none().0,
4325 flags.into_glib(),
4326 mount_operation.map(|p| p.as_ref()).to_glib_none().0,
4327 cancellable.map(|p| p.as_ref()).to_glib_none().0,
4328 Some(callback),
4329 Box_::into_raw(user_data) as *mut _,
4330 );
4331 }
4332 }
4333
4334 fn stop_mountable_future(
4335 &self,
4336 flags: MountUnmountFlags,
4337 mount_operation: Option<&(impl IsA<MountOperation> + Clone + 'static)>,
4338 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
4339 let mount_operation = mount_operation.map(ToOwned::to_owned);
4340 Box_::pin(crate::GioFuture::new(
4341 self,
4342 move |obj, cancellable, send| {
4343 obj.stop_mountable(
4344 flags,
4345 mount_operation.as_ref().map(::std::borrow::Borrow::borrow),
4346 Some(cancellable),
4347 move |res| {
4348 send.resolve(res);
4349 },
4350 );
4351 },
4352 ))
4353 }
4354
4355 /// Checks if @self supports thread-default main contexts
4356 /// (see [`glib::MainContext::push_thread_default()`][crate::glib::MainContext::push_thread_default()])
4357 /// If this returns [`false`], you cannot perform asynchronous operations on
4358 /// @self in a thread that has a thread-default context.
4359 ///
4360 /// # Returns
4361 ///
4362 /// Whether or not @self supports thread-default contexts.
4363 #[doc(alias = "g_file_supports_thread_contexts")]
4364 fn supports_thread_contexts(&self) -> bool {
4365 unsafe {
4366 from_glib(ffi::g_file_supports_thread_contexts(
4367 self.as_ref().to_glib_none().0,
4368 ))
4369 }
4370 }
4371
4372 /// Sends @self to the "Trashcan", if possible. This is similar to
4373 /// deleting it, but the user can recover it before emptying the trashcan.
4374 /// Trashing is disabled for system mounts by default (see
4375 /// g_unix_mount_entry_is_system_internal()), so this call can return the
4376 /// [`IOErrorEnum::NotSupported`][crate::IOErrorEnum::NotSupported] error. Since GLib 2.66, the `x-gvfs-notrash` unix
4377 /// mount option can be used to disable g_file_trash() support for particular
4378 /// mounts, the [`IOErrorEnum::NotSupported`][crate::IOErrorEnum::NotSupported] error will be returned in that case.
4379 /// Since 2.82, the `x-gvfs-trash` unix mount option can be used to enable
4380 /// g_file_trash() support for particular system mounts.
4381 ///
4382 /// If @cancellable is not [`None`], then the operation can be cancelled by
4383 /// triggering the cancellable object from another thread. If the operation
4384 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4385 /// ## `cancellable`
4386 /// optional #GCancellable object,
4387 /// [`None`] to ignore
4388 ///
4389 /// # Returns
4390 ///
4391 /// [`true`] on successful trash, [`false`] otherwise.
4392 #[doc(alias = "g_file_trash")]
4393 fn trash(&self, cancellable: Option<&impl IsA<Cancellable>>) -> Result<(), glib::Error> {
4394 unsafe {
4395 let mut error = std::ptr::null_mut();
4396 let is_ok = ffi::g_file_trash(
4397 self.as_ref().to_glib_none().0,
4398 cancellable.map(|p| p.as_ref()).to_glib_none().0,
4399 &mut error,
4400 );
4401 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
4402 if error.is_null() {
4403 Ok(())
4404 } else {
4405 Err(from_glib_full(error))
4406 }
4407 }
4408 }
4409
4410 /// Asynchronously sends @self to the Trash location, if possible.
4411 /// ## `io_priority`
4412 /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
4413 /// ## `cancellable`
4414 /// optional #GCancellable object,
4415 /// [`None`] to ignore
4416 /// ## `callback`
4417 /// a #GAsyncReadyCallback to call
4418 /// when the request is satisfied
4419 #[doc(alias = "g_file_trash_async")]
4420 fn trash_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
4421 &self,
4422 io_priority: glib::Priority,
4423 cancellable: Option<&impl IsA<Cancellable>>,
4424 callback: P,
4425 ) {
4426 let main_context = glib::MainContext::ref_thread_default();
4427 let is_main_context_owner = main_context.is_owner();
4428 let has_acquired_main_context = (!is_main_context_owner)
4429 .then(|| main_context.acquire().ok())
4430 .flatten();
4431 assert!(
4432 is_main_context_owner || has_acquired_main_context.is_some(),
4433 "Async operations only allowed if the thread is owning the MainContext"
4434 );
4435
4436 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
4437 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
4438 unsafe extern "C" fn trash_async_trampoline<
4439 P: FnOnce(Result<(), glib::Error>) + 'static,
4440 >(
4441 _source_object: *mut glib::gobject_ffi::GObject,
4442 res: *mut crate::ffi::GAsyncResult,
4443 user_data: glib::ffi::gpointer,
4444 ) {
4445 let mut error = std::ptr::null_mut();
4446 ffi::g_file_trash_finish(_source_object as *mut _, res, &mut error);
4447 let result = if error.is_null() {
4448 Ok(())
4449 } else {
4450 Err(from_glib_full(error))
4451 };
4452 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
4453 Box_::from_raw(user_data as *mut _);
4454 let callback: P = callback.into_inner();
4455 callback(result);
4456 }
4457 let callback = trash_async_trampoline::<P>;
4458 unsafe {
4459 ffi::g_file_trash_async(
4460 self.as_ref().to_glib_none().0,
4461 io_priority.into_glib(),
4462 cancellable.map(|p| p.as_ref()).to_glib_none().0,
4463 Some(callback),
4464 Box_::into_raw(user_data) as *mut _,
4465 );
4466 }
4467 }
4468
4469 fn trash_future(
4470 &self,
4471 io_priority: glib::Priority,
4472 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
4473 Box_::pin(crate::GioFuture::new(
4474 self,
4475 move |obj, cancellable, send| {
4476 obj.trash_async(io_priority, Some(cancellable), move |res| {
4477 send.resolve(res);
4478 });
4479 },
4480 ))
4481 }
4482
4483 /// Unmounts a file of type [`FileType::Mountable`][crate::FileType::Mountable].
4484 ///
4485 /// If @cancellable is not [`None`], then the operation can be cancelled by
4486 /// triggering the cancellable object from another thread. If the operation
4487 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
4488 ///
4489 /// When the operation is finished, @callback will be called.
4490 /// You can then call g_file_unmount_mountable_finish() to get
4491 /// the result of the operation.
4492 /// ## `flags`
4493 /// flags affecting the operation
4494 /// ## `mount_operation`
4495 /// a #GMountOperation,
4496 /// or [`None`] to avoid user interaction
4497 /// ## `cancellable`
4498 /// optional #GCancellable object,
4499 /// [`None`] to ignore
4500 /// ## `callback`
4501 /// a #GAsyncReadyCallback
4502 /// to call when the request is satisfied
4503 #[doc(alias = "g_file_unmount_mountable_with_operation")]
4504 fn unmount_mountable_with_operation<P: FnOnce(Result<(), glib::Error>) + 'static>(
4505 &self,
4506 flags: MountUnmountFlags,
4507 mount_operation: Option<&impl IsA<MountOperation>>,
4508 cancellable: Option<&impl IsA<Cancellable>>,
4509 callback: P,
4510 ) {
4511 let main_context = glib::MainContext::ref_thread_default();
4512 let is_main_context_owner = main_context.is_owner();
4513 let has_acquired_main_context = (!is_main_context_owner)
4514 .then(|| main_context.acquire().ok())
4515 .flatten();
4516 assert!(
4517 is_main_context_owner || has_acquired_main_context.is_some(),
4518 "Async operations only allowed if the thread is owning the MainContext"
4519 );
4520
4521 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
4522 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
4523 unsafe extern "C" fn unmount_mountable_with_operation_trampoline<
4524 P: FnOnce(Result<(), glib::Error>) + 'static,
4525 >(
4526 _source_object: *mut glib::gobject_ffi::GObject,
4527 res: *mut crate::ffi::GAsyncResult,
4528 user_data: glib::ffi::gpointer,
4529 ) {
4530 let mut error = std::ptr::null_mut();
4531 ffi::g_file_unmount_mountable_with_operation_finish(
4532 _source_object as *mut _,
4533 res,
4534 &mut error,
4535 );
4536 let result = if error.is_null() {
4537 Ok(())
4538 } else {
4539 Err(from_glib_full(error))
4540 };
4541 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
4542 Box_::from_raw(user_data as *mut _);
4543 let callback: P = callback.into_inner();
4544 callback(result);
4545 }
4546 let callback = unmount_mountable_with_operation_trampoline::<P>;
4547 unsafe {
4548 ffi::g_file_unmount_mountable_with_operation(
4549 self.as_ref().to_glib_none().0,
4550 flags.into_glib(),
4551 mount_operation.map(|p| p.as_ref()).to_glib_none().0,
4552 cancellable.map(|p| p.as_ref()).to_glib_none().0,
4553 Some(callback),
4554 Box_::into_raw(user_data) as *mut _,
4555 );
4556 }
4557 }
4558
4559 fn unmount_mountable_with_operation_future(
4560 &self,
4561 flags: MountUnmountFlags,
4562 mount_operation: Option<&(impl IsA<MountOperation> + Clone + 'static)>,
4563 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
4564 let mount_operation = mount_operation.map(ToOwned::to_owned);
4565 Box_::pin(crate::GioFuture::new(
4566 self,
4567 move |obj, cancellable, send| {
4568 obj.unmount_mountable_with_operation(
4569 flags,
4570 mount_operation.as_ref().map(::std::borrow::Borrow::borrow),
4571 Some(cancellable),
4572 move |res| {
4573 send.resolve(res);
4574 },
4575 );
4576 },
4577 ))
4578 }
4579}
4580
4581impl<O: IsA<File>> FileExt for O {}