diff --git a/rust-bindings/rust/src/repo.rs b/rust-bindings/rust/src/repo.rs index 8a1a12b8..e84aa198 100644 --- a/rust-bindings/rust/src/repo.rs +++ b/rust-bindings/rust/src/repo.rs @@ -1,6 +1,6 @@ #[cfg(any(feature = "v2016_4", feature = "dox"))] use crate::RepoListRefsExtFlags; -use crate::{Checksum, Repo}; +use crate::{Checksum, ObjectName, ObjectType, Repo}; use gio; use glib; use glib::translate::*; @@ -11,7 +11,6 @@ use ostree_sys; use std::collections::{HashMap, HashSet}; use std::path::Path; use std::ptr; -use ObjectName; unsafe extern "C" fn read_variant_table( _key: glib_sys::gpointer, @@ -142,4 +141,31 @@ impl Repo { } } } + + pub fn write_metadata>( + &self, + objtype: ObjectType, + expected_checksum: Option<&str>, + object: &glib::Variant, + cancellable: Option<&P>, + ) -> Result { + unsafe { + let mut error = ptr::null_mut(); + let mut out_csum = ptr::null_mut(); + let _ = ostree_sys::fixed::ostree_repo_write_metadata( + self.to_glib_none().0, + objtype.to_glib(), + expected_checksum.to_glib_none().0, + object.to_glib_none().0, + &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 4f49eeae..375f5a40 100644 --- a/rust-bindings/rust/sys/src/manual.rs +++ b/rust-bindings/rust/sys/src/manual.rs @@ -1,7 +1,7 @@ pub use libc::stat; pub mod fixed { - use crate::OstreeRepo; + use crate::{OstreeObjectType, OstreeRepo}; use glib::gboolean; use libc::c_char; @@ -15,5 +15,15 @@ pub mod fixed { cancellable: *mut gio::GCancellable, error: *mut *mut glib::GError, ) -> gboolean; + + pub fn ostree_repo_write_metadata( + self_: *mut OstreeRepo, + objtype: OstreeObjectType, + expected_checksum: *const c_char, + object: *mut glib::GVariant, + 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 5c5cba17..16d52737 100644 --- a/rust-bindings/rust/tests/repo/mod.rs +++ b/rust-bindings/rust/tests/repo/mod.rs @@ -101,17 +101,33 @@ fn should_write_content_to_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()); + match obj.object_type() { + ObjectType::File => copy_file(&src, &dest, &obj), + _ => copy_metadata(&src, &dest, &obj), } } } + +fn copy_file(src: &TestRepo, dest: &TestRepo, obj: &ObjectName) { + let (stream, len) = src + .repo + .load_object_stream(obj.object_type(), obj.checksum(), NONE_CANCELLABLE) + .expect("load object stream"); + let out_csum = dest + .repo + .write_content(None, &stream, len, NONE_CANCELLABLE) + .expect("write content"); + assert_eq!(out_csum.to_string(), obj.checksum()); +} + +fn copy_metadata(src: &TestRepo, dest: &TestRepo, obj: &ObjectName) -> () { + let data = src + .repo + .load_variant(obj.object_type(), obj.checksum()) + .expect("load variant"); + let out_csum = dest + .repo + .write_metadata(obj.object_type(), None, &data, NONE_CANCELLABLE) + .expect("write metadata"); + assert_eq!(out_csum.to_string(), obj.checksum()); +}