diff --git a/rust-bindings/conf/ostree.toml b/rust-bindings/conf/ostree.toml index 57c2a793..ec2b594d 100644 --- a/rust-bindings/conf/ostree.toml +++ b/rust-bindings/conf/ostree.toml @@ -173,6 +173,11 @@ concurrency = "send" pattern = "^(load_file)$" ignore = true + [[object.function]] + # [MANUAL] hash table with variants + pattern = "^(list_commit_objects_starting_with)$" + ignore = true + [[object]] name = "OSTree.RepoFinder" status = "generate" diff --git a/rust-bindings/src/repo.rs b/rust-bindings/src/repo.rs index 6aeccff5..1e3e90bc 100644 --- a/rust-bindings/src/repo.rs +++ b/rust-bindings/src/repo.rs @@ -556,4 +556,52 @@ impl Repo { // Safety: We know the variant type will match since we just passed it above Ok(crate::DirMetaParsed::from_variant(&v).unwrap()) } + + /// List all commit objects; an optional prefix filter may be applied. + #[doc(alias = "ostree_repo_list_commit_objects_starting_with")] + pub fn list_commit_objects_starting_with>( + &self, + prefix: Option<&str>, + cancellable: Option<&P>, + ) -> Result, glib::Error> { + use glib::ffi::gpointer; + let prefix = prefix.unwrap_or(""); + unsafe { + let repo = self.to_glib_none().0; + let mut commits = ptr::null_mut(); + let cancellable = cancellable.map(|p| p.as_ref()).to_glib_none().0; + let mut error = ptr::null_mut(); + let prefix = prefix.to_glib_none(); + let r = ffi::ostree_repo_list_commit_objects_starting_with( + repo, + prefix.0, + &mut commits, + cancellable, + &mut error, + ); + if !error.is_null() { + assert_eq!(r, 0); + return Err(from_glib_full(error)); + } + assert_ne!(r, 0); + let mut ret = HashSet::with_capacity(glib::ffi::g_hash_table_size(commits) as usize); + unsafe extern "C" fn visit_hash_table( + key: *mut libc::c_void, + _value: gpointer, + r: *mut libc::c_void, + ) -> glib::ffi::gboolean { + let key: glib::Variant = from_glib_none(key as *const glib::ffi::GVariant); + let checksum = crate::object_name_deserialize(&key).0; + let r = &mut *(r as *mut HashSet); + r.insert(checksum); + true.into() + } + glib::ffi::g_hash_table_foreach_remove( + commits, + Some(visit_hash_table), + &mut ret as *mut HashSet as *mut _, + ); + Ok(ret) + } + } } diff --git a/rust-bindings/tests/repo/mod.rs b/rust-bindings/tests/repo/mod.rs index 703dc735..0a94eb9f 100644 --- a/rust-bindings/tests/repo/mod.rs +++ b/rust-bindings/tests/repo/mod.rs @@ -26,6 +26,33 @@ fn should_commit_content_to_repo_and_list_refs_again() { assert_eq!(checksum, refs["test"]); } +#[test] +fn list_commits() { + let cancellable = gio::NONE_CANCELLABLE; + let test_repo = TestRepo::new(); + + for prefix in [None, Some("a"), Some("0abcde")] { + let commits = test_repo + .repo + .list_commit_objects_starting_with(prefix, cancellable) + .unwrap(); + assert_eq!(commits.len(), 0); + } + + let rev = test_repo.test_commit("testref"); + + for prefix in [None, Some(&rev[0..1]), Some(&rev[0..5])] { + let commits = test_repo + .repo + .list_commit_objects_starting_with(prefix, cancellable) + .unwrap() + .into_iter() + .collect::>(); + assert_eq!(commits.len(), 1); + assert_eq!(commits[0].as_str(), rev.as_str()); + } +} + #[test] #[cfg(feature = "cap-std-apis")] fn cap_std_commit() {