1use std::ops::{Deref, DerefMut};
2use std::ptr;
3use std::slice;
4use std::str;
5
6use crate::raw;
7use crate::util::Binding;
8
9pub 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 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 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}