diff --git a/rust/src/lib.rs b/rust/src/lib.rs index fece520656..1cbeabd761 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -47,6 +47,8 @@ mod collection_ref; pub use crate::collection_ref::*; mod functions; pub use crate::functions::*; +mod mutable_tree; +pub use crate::mutable_tree::*; #[cfg(any(feature = "v2019_3", feature = "dox"))] mod kernel_args; #[cfg(any(feature = "v2019_3", feature = "dox"))] diff --git a/rust/src/mutable_tree.rs b/rust/src/mutable_tree.rs new file mode 100644 index 0000000000..dd59217289 --- /dev/null +++ b/rust/src/mutable_tree.rs @@ -0,0 +1,46 @@ +use crate::MutableTree; +use glib::{self, translate::*}; +use std::collections::HashMap; + +impl MutableTree { + #[doc(alias = "ostree_mutable_tree_get_files")] + /// Create a copy of the files in this mutable tree. + /// Unlike the C version of this function, a copy is made because providing + /// read-write access would introduce the potential for use-after-free bugs. + pub fn copy_files(&self) -> HashMap { + unsafe { + let v = ffi::ostree_mutable_tree_get_files(self.to_glib_none().0); + HashMap::from_glib_none_num(v, 1) + } + } + + #[doc(alias = "ostree_mutable_tree_get_subdirs")] + /// Create a copy of the directories in this mutable tree. + /// Unlike the C version of this function, a copy is made because providing + /// read-write access would introduce the potential for use-after-free bugs. + pub fn copy_subdirs(&self) -> HashMap { + use glib::ffi::gpointer; + + unsafe { + let v = ffi::ostree_mutable_tree_get_subdirs(self.to_glib_none().0); + unsafe extern "C" fn visit_hash_table( + key: gpointer, + value: gpointer, + hash_map: gpointer, + ) { + let key: String = from_glib_none(key as *const libc::c_char); + let value: MutableTree = from_glib_none(value as *const ffi::OstreeMutableTree); + let hash_map: &mut HashMap = + &mut *(hash_map as *mut HashMap); + hash_map.insert(key, value); + } + let mut map = HashMap::with_capacity(glib::ffi::g_hash_table_size(v) as usize); + glib::ffi::g_hash_table_foreach( + v, + Some(visit_hash_table), + &mut map as *mut HashMap as *mut _, + ); + map + } + } +} diff --git a/rust/tests/util/mod.rs b/rust/tests/util/mod.rs index 2bc4efbf78..472bf4553e 100644 --- a/rust/tests/util/mod.rs +++ b/rust/tests/util/mod.rs @@ -50,6 +50,8 @@ impl CapTestRepo { pub fn create_mtree(repo: &ostree::Repo) -> ostree::MutableTree { let mtree = ostree::MutableTree::new(); + assert_eq!(mtree.copy_files().len(), 0); + assert_eq!(mtree.copy_subdirs().len(), 0); let file = gio::File::for_path( Path::new(env!("CARGO_MANIFEST_DIR")) .join("tests")