diff --git a/rust-bindings/rust/src/repo.rs b/rust-bindings/rust/src/repo.rs index cc9cc10f..8a1a12b8 100644 --- a/rust-bindings/rust/src/repo.rs +++ b/rust-bindings/rust/src/repo.rs @@ -1,6 +1,6 @@ -use crate::Repo; #[cfg(any(feature = "v2016_4", feature = "dox"))] use crate::RepoListRefsExtFlags; +use crate::{Checksum, Repo}; use gio; use glib; use glib::translate::*; @@ -115,4 +115,31 @@ impl Repo { } } } + + pub fn write_content, Q: IsA>( + &self, + expected_checksum: Option<&str>, + object_input: &P, + length: u64, + cancellable: Option<&Q>, + ) -> Result { + unsafe { + let mut error = ptr::null_mut(); + let mut out_csum = ptr::null_mut(); + let _ = ostree_sys::fixed::ostree_repo_write_content( + self.to_glib_none().0, + expected_checksum.to_glib_none().0, + object_input.as_ref().to_glib_none().0, + length, + &mut out_csum, + cancellable.map(|p| p.as_ref()).to_glib_none().0, + &mut error, + ); + if error.is_null() { + Ok(from_glib_full(out_csum)) + } else { + Err(from_glib_full(error)) + } + } + } } diff --git a/rust-bindings/rust/sys/src/manual.rs b/rust-bindings/rust/sys/src/manual.rs index 4c5af957..4f49eeae 100644 --- a/rust-bindings/rust/sys/src/manual.rs +++ b/rust-bindings/rust/sys/src/manual.rs @@ -1 +1,19 @@ -pub use libc::stat as stat; +pub use libc::stat; + +pub mod fixed { + use crate::OstreeRepo; + use glib::gboolean; + use libc::c_char; + + extern "C" { + pub fn ostree_repo_write_content( + self_: *mut OstreeRepo, + expected_checksum: *const c_char, + object_input: *mut gio::GInputStream, + length: u64, + out_csum: *mut *mut [u8; 32], + cancellable: *mut gio::GCancellable, + error: *mut *mut glib::GError, + ) -> gboolean; + } +} diff --git a/rust-bindings/rust/tests/repo/mod.rs b/rust-bindings/rust/tests/repo/mod.rs index c0385ba8..5c5cba17 100644 --- a/rust-bindings/rust/tests/repo/mod.rs +++ b/rust-bindings/rust/tests/repo/mod.rs @@ -88,3 +88,30 @@ fn should_checkout_tree() { assert_test_file(checkout_dir.path()); } + +#[test] +fn should_write_content_to_repo() { + let src = TestRepo::new(); + let mtree = create_mtree(&src.repo); + let checksum = commit(&src.repo, &mtree, "test"); + + let dest = TestRepo::new(); + let objects = src + .repo + .traverse_commit(&checksum, -1, NONE_CANCELLABLE) + .expect("traverse"); + for obj in objects { + let (stream, len) = src + .repo + .load_object_stream(obj.object_type(), obj.checksum(), NONE_CANCELLABLE) + .expect("load object stream"); + if obj.object_type() == ObjectType::File { + let out_csum = dest + .repo + .write_content(None, &stream, len, NONE_CANCELLABLE) + .expect("write content"); + + assert_eq!(out_csum.to_string(), obj.checksum()); + } + } +}