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