aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libgit-sys/src
diff options
context:
space:
mode:
authorJosh Steadmon <steadmon@google.com>2025-01-28 14:01:38 -0800
committerJunio C Hamano <gitster@pobox.com>2025-01-28 14:45:47 -0800
commite7f8bf125c078004232e254e71b97226c4fed81b (patch)
treebc14f55bd4768731a7e47ccb3b985edd8231fcf1 /contrib/libgit-sys/src
parent3f8f2abe05c0aeb0ea60768d44a99261ed456d44 (diff)
downloadgit-e7f8bf125c078004232e254e71b97226c4fed81b.tar.gz
libgit-sys: introduce Rust wrapper for libgit.a
Introduce libgit-sys, a Rust wrapper crate that allows Rust code to call functions in libgit.a. This initial patch defines build rules and an interface that exposes user agent string getter functions as a proof of concept. This library can be tested with `cargo test`. In later commits, a higher-level library containing a more Rust-friendly interface will be added at `contrib/libgit-rs`. Symbols in libgit can collide with symbols from other libraries such as libgit2. We avoid this by first exposing library symbols in public_symbol_export.[ch]. These symbols are prepended with "libgit_" to avoid collisions and set to visible using a visibility pragma. In build.rs, Rust builds contrib/libgit-rs/libgit-sys/libgitpub.a, which also contains libgit.a and other dependent libraries, with -fvisibility=hidden to hide all symbols within those libraries that haven't been exposed with a visibility pragma. Co-authored-by: Kyle Lippincott <spectral@google.com> Co-authored-by: Calvin Wan <calvinwan@google.com> Signed-off-by: Calvin Wan <calvinwan@google.com> Signed-off-by: Kyle Lippincott <spectral@google.com> Signed-off-by: Josh Steadmon <steadmon@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'contrib/libgit-sys/src')
-rw-r--r--contrib/libgit-sys/src/lib.rs46
1 files changed, 46 insertions, 0 deletions
diff --git a/contrib/libgit-sys/src/lib.rs b/contrib/libgit-sys/src/lib.rs
new file mode 100644
index 0000000000..d4853f3074
--- /dev/null
+++ b/contrib/libgit-sys/src/lib.rs
@@ -0,0 +1,46 @@
+#[cfg(has_std__ffi__c_char)]
+use std::ffi::c_char;
+
+#[cfg(not(has_std__ffi__c_char))]
+#[allow(non_camel_case_types)]
+pub type c_char = i8;
+
+extern crate libz_sys;
+
+extern "C" {
+ pub fn libgit_user_agent() -> *const c_char;
+ pub fn libgit_user_agent_sanitized() -> *const c_char;
+}
+
+#[cfg(test)]
+mod tests {
+ use std::ffi::CStr;
+
+ use super::*;
+
+ #[test]
+ fn user_agent_starts_with_git() {
+ let c_str = unsafe { CStr::from_ptr(libgit_user_agent()) };
+ let agent = c_str
+ .to_str()
+ .expect("User agent contains invalid UTF-8 data");
+ assert!(
+ agent.starts_with("git/"),
+ r#"Expected user agent to start with "git/", got: {}"#,
+ agent
+ );
+ }
+
+ #[test]
+ fn sanitized_user_agent_starts_with_git() {
+ let c_str = unsafe { CStr::from_ptr(libgit_user_agent_sanitized()) };
+ let agent = c_str
+ .to_str()
+ .expect("Sanitized user agent contains invalid UTF-8 data");
+ assert!(
+ agent.starts_with("git/"),
+ r#"Expected user agent to start with "git/", got: {}"#,
+ agent
+ );
+ }
+}