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