Skip to main content

git2/
buf.rs

1use std::ops::{Deref, DerefMut};
2use std::ptr;
3use std::slice;
4use std::str;
5
6use crate::raw;
7use crate::util::Binding;
8
9/// A structure to wrap an intermediate buffer used by libgit2.
10///
11/// A buffer can be thought of a `Vec<u8>`, but the `Vec` type is not used to
12/// avoid copying data back and forth.
13pub struct Buf {
14    raw: raw::git_buf,
15}
16
17impl Default for Buf {
18    fn default() -> Self {
19        Self::new()
20    }
21}
22
23impl Buf {
24    /// Creates a new empty buffer.
25    pub fn new() -> Buf {
26        crate::init();
27        unsafe {
28            Binding::from_raw(&mut raw::git_buf {
29                ptr: ptr::null_mut(),
30                size: 0,
31                reserved: 0,
32            } as *mut _)
33        }
34    }
35
36    /// Attempt to view this buffer as a string slice.
37    ///
38    /// Returns `None` if the buffer is not valid utf-8.
39    pub fn as_str(&self) -> Option<&str> {
40        str::from_utf8(&**self).ok()
41    }
42}
43
44impl Deref for Buf {
45    type Target = [u8];
46    fn deref(&self) -> &[u8] {
47        if self.raw.ptr.is_null() {
48            return &[];
49        }
50        unsafe { slice::from_raw_parts(self.raw.ptr as *const u8, self.raw.size as usize) }
51    }
52}
53
54impl DerefMut for Buf {
55    fn deref_mut(&mut self) -> &mut [u8] {
56        if self.raw.ptr.is_null() {
57            return &mut [];
58        }
59        unsafe { slice::from_raw_parts_mut(self.raw.ptr as *mut u8, self.raw.size as usize) }
60    }
61}
62
63impl Binding for Buf {
64    type Raw = *mut raw::git_buf;
65    unsafe fn from_raw(raw: *mut raw::git_buf) -> Buf {
66        Buf { raw: *raw }
67    }
68    fn raw(&self) -> *mut raw::git_buf {
69        &self.raw as *const _ as *mut _
70    }
71}
72
73impl Drop for Buf {
74    fn drop(&mut self) {
75        unsafe { raw::git_buf_dispose(&mut self.raw) }
76    }
77}
78
79#[test]
80fn empty_buf() {
81    let mut buf = Buf::new();
82    let x: &[u8] = &*buf;
83    assert_eq!(x.len(), 0);
84    let x: &mut [u8] = &mut *buf;
85    assert_eq!(x.len(), 0);
86}