Thread (20 messages) 20 messages, 4 authors, 2025-10-08

Re: [PATCH 2/2] libgit-rs: add get_bool() method to ConfigSet

From: Phillip Wood <hidden>
Date: 2025-09-26 09:58:07

On 25/09/2025 12:44, ionnss via GitGitGadget wrote:
From: ionnss <redacted>

Add support for parsing boolean configuration values in the Rust
ConfigSet API. The method follows Git's standard boolean parsing
rules, accepting true/yes/on/1 as true and false/no/off/0 as false.

The implementation reuses the existing get_string() infrastructure
and adds case-insensitive boolean parsing logic.
It's nice to know that someone is using the rust bindings. The code in 
contrib/libgit-rs is intended to be safe wrappers around the unsafe 
functions in contrib/libgit-sys which wrap git's C code. I think what we 
need to do here is add a binding for git_configset_get_bool() to 
libgit-sys and then wrap that in libgit-rs. We don't want to start 
implementing the parsing separately as they'll inevitably end up 
behaving differently to git. For example what you have here parses "00" 
or "100" differently to git.

Thanks

Phillip
quoted hunk ↗ jump to hunk
Signed-off-by: ionnss <redacted>
---
  contrib/libgit-rs/src/config.rs    | 24 ++++++++++++++++++++++++
  contrib/libgit-rs/testdata/config3 |  2 ++
  2 files changed, 26 insertions(+)
diff --git a/contrib/libgit-rs/src/config.rs b/contrib/libgit-rs/src/config.rs
index 6bf04845c8..3f4a32c72d 100644
--- a/contrib/libgit-rs/src/config.rs
+++ b/contrib/libgit-rs/src/config.rs
@@ -68,6 +68,26 @@ impl ConfigSet {
              Some(owned_str)
          }
      }
+
+    pub fn get_bool(&mut self, key: &str) -> Option<bool> {
+        let key = CString::new(key).expect("Couldn't convert key to CString");
+        let mut val: *mut c_char = std::ptr::null_mut();
+        unsafe {
+            if libgit_configset_get_string(self.0, key.as_ptr(), &mut val as *mut *mut c_char) != 0
+            {
+                return None;
+            }
+            let borrowed_str = CStr::from_ptr(val);
+            let owned_str =
+                String::from(borrowed_str.to_str().expect("Couldn't convert val to str"));
+            free(val as *mut c_void); // Free the xstrdup()ed pointer from the C side
+            match owned_str.to_lowercase().as_str() {
+                "true" | "yes" | "on" | "1" => Some(true),
+                "false" | "no" | "off" | "0" => Some(false),
+                _ => None,
+            }
+        }
+    }
  }
  
  impl Default for ConfigSet {
@@ -102,5 +122,9 @@ mod tests {
          assert_eq!(cs.get_int("trace2.eventNesting"), Some(3));
          // ConfigSet returns None for missing key
          assert_eq!(cs.get_string("foo.bar"), None);
+        // Test boolean parsing
+        assert_eq!(cs.get_bool("test.booleanValue"), Some(true));
+        // Test missing boolean key
+        assert_eq!(cs.get_bool("missing.boolean"), None);
      }
  }
diff --git a/contrib/libgit-rs/testdata/config3 b/contrib/libgit-rs/testdata/config3
index ca7b9a7c38..83a474ccef 100644
--- a/contrib/libgit-rs/testdata/config3
+++ b/contrib/libgit-rs/testdata/config3
@@ -1,2 +1,4 @@
  [trace2]
  	eventNesting = 3
+[test]
+	booleanValue = true
  
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help