Implement Repo::write_content_async

This commit is contained in:
Felix Krull 2019-09-01 14:19:51 +02:00 committed by Colin Walters
parent bb4e0c5978
commit 8002e06e25
2 changed files with 93 additions and 1 deletions

View File

@ -32,6 +32,12 @@ impl FromGlibPtrFull<*mut [u8; 32]> for Checksum {
}
}
impl FromGlibPtrFull<*mut u8> for Checksum {
unsafe fn from_glib_full(ptr: *mut u8) -> Self {
Checksum::new(ptr as *mut [u8; 32])
}
}
impl fmt::Display for Checksum {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.to_gstring())

View File

@ -1,16 +1,20 @@
#[cfg(any(feature = "v2016_4", feature = "dox"))]
use crate::RepoListRefsExtFlags;
use crate::{Checksum, ObjectName, ObjectType, Repo};
#[cfg(feature = "futures")]
use futures::future;
use gio;
use gio_sys;
use glib;
use glib::translate::*;
use glib::Error;
use glib::IsA;
use glib_sys;
use ostree_sys;
use std::boxed::Box as Box_;
use std::collections::{HashMap, HashSet};
use std::path::Path;
use std::ptr;
use std::{mem::MaybeUninit, ptr};
unsafe extern "C" fn read_variant_table(
_key: glib_sys::gpointer,
@ -168,4 +172,86 @@ impl Repo {
}
}
}
pub fn write_content_async<
P: IsA<gio::InputStream>,
Q: IsA<gio::Cancellable>,
R: FnOnce(Result<Checksum, Error>) + Send + 'static,
>(
&self,
expected_checksum: Option<&str>,
object: &P,
length: u64,
cancellable: Option<&Q>,
callback: R,
) {
let user_data: Box<R> = Box::new(callback);
unsafe extern "C" fn write_content_async_trampoline<
R: FnOnce(Result<Checksum, Error>) + Send + 'static,
>(
_source_object: *mut gobject_sys::GObject,
res: *mut gio_sys::GAsyncResult,
user_data: glib_sys::gpointer,
) {
let mut error = ptr::null_mut();
let mut out_csum = MaybeUninit::uninit();
let _ = ostree_sys::ostree_repo_write_content_finish(
_source_object as *mut _,
res,
out_csum.as_mut_ptr(),
&mut error,
);
let out_csum = out_csum.assume_init();
let result = if error.is_null() {
Ok(Checksum::from_glib_full(out_csum))
} else {
Err(from_glib_full(error))
};
let callback: Box<R> = Box::from_raw(user_data as *mut _);
callback(result);
}
let callback = write_content_async_trampoline::<R>;
unsafe {
ostree_sys::ostree_repo_write_content_async(
self.to_glib_none().0,
expected_checksum.to_glib_none().0,
object.as_ref().to_glib_none().0,
length,
cancellable.map(|p| p.as_ref()).to_glib_none().0,
Some(callback),
Box::into_raw(user_data) as *mut _,
);
}
}
#[cfg(feature = "futures")]
pub fn write_content_async_future<P: IsA<gio::InputStream> + Clone + 'static>(
&self,
expected_checksum: Option<&str>,
object: &P,
length: u64,
) -> Box_<dyn future::Future<Output = Result<Checksum, Error>> + std::marker::Unpin> {
use fragile::Fragile;
use gio::GioFuture;
let expected_checksum = expected_checksum.map(ToOwned::to_owned);
let object = object.clone();
GioFuture::new(self, move |obj, send| {
let cancellable = gio::Cancellable::new();
let send = Fragile::new(send);
obj.write_content_async(
expected_checksum
.as_ref()
.map(::std::borrow::Borrow::borrow),
&object,
length,
Some(&cancellable),
move |res| {
let _ = send.into_inner().send(res);
},
);
cancellable
})
}
}