1 use std::ops::{Deref, DerefMut};
2 use std::ptr;
3 use std::slice;
4 use std::str;
5 
6 use crate::raw;
7 use 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.
13 pub struct Buf {
14     raw: raw::git_buf,
15 }
16 
17 impl Default for Buf {
default() -> Self18     fn default() -> Self {
19         Self::new()
20     }
21 }
22 
23 impl Buf {
24     /// Creates a new empty buffer.
new() -> Buf25     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                 asize: 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.
as_str(&self) -> Option<&str>39     pub fn as_str(&self) -> Option<&str> {
40         str::from_utf8(&**self).ok()
41     }
42 }
43 
44 impl Deref for Buf {
45     type Target = [u8];
deref(&self) -> &[u8]46     fn deref(&self) -> &[u8] {
47         unsafe { slice::from_raw_parts(self.raw.ptr as *const u8, self.raw.size as usize) }
48     }
49 }
50 
51 impl DerefMut for Buf {
deref_mut(&mut self) -> &mut [u8]52     fn deref_mut(&mut self) -> &mut [u8] {
53         unsafe { slice::from_raw_parts_mut(self.raw.ptr as *mut u8, self.raw.size as usize) }
54     }
55 }
56 
57 impl Binding for Buf {
58     type Raw = *mut raw::git_buf;
from_raw(raw: *mut raw::git_buf) -> Buf59     unsafe fn from_raw(raw: *mut raw::git_buf) -> Buf {
60         Buf { raw: *raw }
61     }
raw(&self) -> *mut raw::git_buf62     fn raw(&self) -> *mut raw::git_buf {
63         &self.raw as *const _ as *mut _
64     }
65 }
66 
67 impl Drop for Buf {
drop(&mut self)68     fn drop(&mut self) {
69         unsafe { raw::git_buf_dispose(&mut self.raw) }
70     }
71 }
72