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