From 887f5b09be09cd2b8fa7fc2ef2242ba636039789 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 26 Feb 2022 08:46:50 -0500 Subject: [PATCH] repo: Add `query_file` API The underlying `ostree_repo_load_file()` API has the caller pass `NULL` for output arguments it doesn't want. This isn't sanely bindable in Rust - what the generator does is always request all values, but maps them all to `Option`. The main cases are where a user wants either metadata, or both metadata and content. This API gives just metadata; it's a bit more efficient as we don't need to open the file, and doesn't require the caller to `unwrap()`. --- rust-bindings/rust/src/repo.rs | 31 ++++++++++++++++++++++++++++ rust-bindings/rust/tests/repo/mod.rs | 9 ++++++++ 2 files changed, 40 insertions(+) diff --git a/rust-bindings/rust/src/repo.rs b/rust-bindings/rust/src/repo.rs index 147199c9..35a15248 100644 --- a/rust-bindings/rust/src/repo.rs +++ b/rust-bindings/rust/src/repo.rs @@ -269,6 +269,37 @@ impl Repo { Ok(self.resolve_rev(refspec, false)?.unwrap()) } + /// Query metadata for a content object. + /// + /// This is similar to [`load_file`], but is more efficient if reading the file content is not needed. + pub fn query_file>( + &self, + checksum: &str, + cancellable: Option<&P>, + ) -> Result<(gio::FileInfo, glib::Variant), glib::Error> { + unsafe { + let mut out_file_info = ptr::null_mut(); + let mut out_xattrs = ptr::null_mut(); + let mut error = ptr::null_mut(); + let r = ffi::ostree_repo_load_file( + self.to_glib_none().0, + checksum.to_glib_none().0, + ptr::null_mut(), + &mut out_file_info, + &mut out_xattrs, + cancellable.map(|p| p.as_ref()).to_glib_none().0, + &mut error, + ); + if error.is_null() { + debug_assert!(r != 0); + Ok((from_glib_full(out_file_info), from_glib_full(out_xattrs))) + } else { + debug_assert_eq!(r, 0); + Err(from_glib_full(error)) + } + } + } + /// Write a content object from provided input. pub fn write_content, Q: IsA>( &self, diff --git a/rust-bindings/rust/tests/repo/mod.rs b/rust-bindings/rust/tests/repo/mod.rs index 5d59aa52..703dc735 100644 --- a/rust-bindings/rust/tests/repo/mod.rs +++ b/rust-bindings/rust/tests/repo/mod.rs @@ -89,6 +89,15 @@ fn repo_traverse_and_read() { .unwrap(); // Right now, the uid/gid are actually that of the test runner assert_eq!(dirmeta.mode, 0o40750); + + let (finfo, _xattrs) = test_repo + .repo + .query_file( + "89f84ca9854a80e85b583e46a115ba4985254437027bad34f0b113219323d3f8", + NONE_CANCELLABLE, + ) + .unwrap(); + assert_eq!(finfo.size(), 5); } #[test]