summary refs log tree commit diff
path: root/libsecret/src/hashtable.rs
diff options
context:
space:
mode:
authorVika <vika@fireburn.ru>2024-10-22 21:52:10 +0300
committerVika <vika@fireburn.ru>2024-10-22 21:52:10 +0300
commitf2f7b6ffec7bf657966353c850d25c6ab218ff7c (patch)
treed4d5cc76474453863a064eb04d75af5353579f5b /libsecret/src/hashtable.rs
parent3bd499a9d696a850a493bf81c01c68aee18c9d7b (diff)
downloadbowl-f2f7b6ffec7bf657966353c850d25c6ab218ff7c.tar.zst
vendor libsecret
The libsecret-rs crate is unmaintained, so I'm vendoring it for
now. Bumping the glib version turned out to be enough.

The exact process I used was:
1. Cloning the repository
2. Making changes
3. `cargo build` to ensure it works
4. `cargo package --no-verify` (b/c it tries to build all crates
separately instead of the entire workspace as a whole)
5. `mkdir libsecret/sys -p`
6. `tar --strip-components 1 -C libsecret -xvf ../libsecret-rs/target/package/libsecret-0.6.0.crate`
7. `tar --strip-components 1 -C libsecret/sys -xvf ../libsecret-rs/target/package/libsecret-sys-0.6.0.crate`

Then `Cargo.toml` is modified to ensure the libsecret and its `-sys`
crate build out of my vendored sources.

In the future, if I gain maintainership of the `libsecret` crate, I
could just revert this commit to make it point back to the upstream.
Diffstat (limited to 'libsecret/src/hashtable.rs')
-rw-r--r--libsecret/src/hashtable.rs63
1 files changed, 63 insertions, 0 deletions
diff --git a/libsecret/src/hashtable.rs b/libsecret/src/hashtable.rs
new file mode 100644
index 0000000..1f42c95
--- /dev/null
+++ b/libsecret/src/hashtable.rs
@@ -0,0 +1,63 @@
+use glib::translate::*;
+use std::collections::HashMap;
+
+use crate::Value;
+
+pub(crate) unsafe fn attribute_names_and_values(
+    entry: HashMap<&str, &str>,
+) -> *mut glib::ffi::GHashTable {
+    let hash_table = glib::ffi::g_hash_table_new_full(
+        Some(glib::ffi::g_str_hash),
+        Some(glib::ffi::g_str_equal),
+        Some(glib::ffi::g_free),
+        Some(glib::ffi::g_free),
+    );
+
+    for (key, val) in entry {
+        let key_ptr: *mut libc::c_char = key.to_glib_full();
+        let val_ptr: *mut libc::c_char = val.to_glib_full();
+        glib::ffi::g_hash_table_insert(hash_table, key_ptr as *mut _, val_ptr as *mut _);
+    }
+
+    hash_table
+}
+
+pub(crate) unsafe fn attribute_names_and_properties(
+    hash_map: HashMap<&str, &glib::Variant>,
+) -> *mut glib::ffi::GHashTable {
+    let hash_table = glib::ffi::g_hash_table_new_full(
+        Some(glib::ffi::g_str_hash),
+        Some(glib::ffi::g_str_equal),
+        Some(glib::ffi::g_free),
+        Some(glib::ffi::g_free),
+    );
+
+    for (name, value) in hash_map {
+        let key_ptr: *mut libc::c_char = name.to_glib_full();
+        glib::ffi::g_hash_table_insert(hash_table, key_ptr as *mut _, value.as_ptr() as _);
+    }
+
+    hash_table
+}
+
+pub(crate) unsafe fn hash_map_from_glib_none(
+    ptr: *mut glib::ffi::GHashTable,
+) -> HashMap<String, Value> {
+    unsafe extern "C" fn read_string_hash_table(
+        key: glib::ffi::gpointer,
+        value: glib::ffi::gpointer,
+        hash_map: glib::ffi::gpointer,
+    ) {
+        let key: String = from_glib_none(key as *const libc::c_char);
+        let value: Value = from_glib_none(value as *const ffi::SecretValue);
+        let hash_map: &mut HashMap<String, Value> = &mut *(hash_map as *mut HashMap<String, Value>);
+        hash_map.insert(key, value);
+    }
+    let mut map = HashMap::with_capacity(glib::ffi::g_hash_table_size(ptr) as usize);
+    glib::ffi::g_hash_table_foreach(
+        ptr,
+        Some(read_string_hash_table),
+        &mut map as *mut HashMap<String, Value> as *mut _,
+    );
+    map
+}