From: brian m. carlson Date: Mon, 27 Oct 2025 00:43:56 GMT Subject: [PATCH 06/14] hash: add a function to look up hash algo structs Message-ID: <20251027004404.2152927-7-sandals@crustytoothpaste.net> In-Reply-To: <20251027004404.2152927-1-sandals@crustytoothpaste.net> In C, it's easy for us to look up a hash algorithm structure by its offset by simply indexing the hash_algos array. However, in Rust, we sometimes need a pointer to pass to a C function, but we have our own hash algorithm abstraction. To get one from the other, let's provide a simple function that looks up the C structure from the offset and expose it in Rust. Signed-off-by: brian m. carlson --- hash.c | 5 +++++ hash.h | 1 + src/hash.rs | 15 +++++++++++++++ 3 files changed, 21 insertions(+) diff --git a/hash.c b/hash.c index 81b4f87027..2f4e88e501 100644 --- a/hash.c +++ b/hash.c @@ -241,6 +241,11 @@ const char *empty_tree_oid_hex(const struct git_hash_algo *algop) return oid_to_hex_r(buf, algop->empty_tree); } +const struct git_hash_algo *hash_algo_ptr_by_offset(uint32_t algo) +{ + return &hash_algos[algo]; +} + uint32_t hash_algo_by_name(const char *name) { if (!name) diff --git a/hash.h b/hash.h index 99c9c2a0a8..c47ac81989 100644 --- a/hash.h +++ b/hash.h @@ -340,6 +340,7 @@ static inline void git_hash_final_oid(struct object_id *oid, struct git_hash_ctx ctx->algop->final_oid_fn(oid, ctx); } +const struct git_hash_algo *hash_algo_ptr_by_offset(uint32_t algo); /* * Return a GIT_HASH_* constant based on the name. Returns GIT_HASH_UNKNOWN if * the name doesn't match a known algorithm. diff --git a/src/hash.rs b/src/hash.rs index 1b9f07489e..a5b9493bd8 100644 --- a/src/hash.rs +++ b/src/hash.rs @@ -10,6 +10,8 @@ // You should have received a copy of the GNU General Public License along // with this program; if not, see . +use std::os::raw::c_void; + pub const GIT_MAX_RAWSZ: usize = 32; /// A binary object ID. @@ -160,4 +162,17 @@ impl HashAlgorithm { HashAlgorithm::SHA256 => &Self::SHA256_NULL_OID, } } + + /// A pointer to the C `struct git_hash_algo` for interoperability with C. + pub fn hash_algo_ptr(self) -> *const c_void { + unsafe { c::hash_algo_ptr_by_offset(self as u32) } + } +} + +pub mod c { + use std::os::raw::c_void; + + extern "C" { + pub fn hash_algo_ptr_by_offset(n: u32) -> *const c_void; + } }