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