1use std::os::raw::c_int;
21
22use pyo3::ffi;
23use pyo3::prelude::*;
24
25pub(crate) const INLINED_U8: usize = 64;
26
27pub type Bytes = smallvec::SmallVec<[u8; INLINED_U8]>;
28
29#[pyclass]
31pub struct Buffer(Bytes);
32
33impl From<Bytes> for Buffer {
34 fn from(inner: Bytes) -> Self {
35 Buffer(inner)
36 }
37}
38
39impl From<Vec<u8>> for Buffer {
40 fn from(inner: Vec<u8>) -> Self {
41 Buffer(inner.into())
42 }
43}
44
45impl From<&[u8]> for Buffer {
46 fn from(inner: &[u8]) -> Self {
47 Buffer(inner.into())
48 }
49}
50
51impl From<&str> for Buffer {
52 fn from(inner: &str) -> Self {
53 Buffer(inner.as_bytes().into())
54 }
55}
56
57impl From<String> for Buffer {
58 fn from(inner: String) -> Self {
59 Buffer(inner.into_bytes().into())
60 }
61}
62
63impl From<Buffer> for Bytes {
64 fn from(buffer: Buffer) -> Self {
65 buffer.0
66 }
67}
68
69impl Buffer {
70 pub fn new(inner: Bytes) -> Self {
71 Buffer(inner)
72 }
73
74 pub fn into_memory_view(self, py: Python) -> PyResult<Py<PyAny>> {
76 let buffer = self.into_py(py);
77
78 unsafe { PyObject::from_owned_ptr_or_err(py, ffi::PyMemoryView_FromObject(buffer.as_ptr())) }
79 }
80
81 pub fn into_memory_view_ref(self, py: Python) -> PyResult<&PyAny> {
83 let buffer = self.into_py(py);
84 let view = unsafe { py.from_owned_ptr_or_err(ffi::PyMemoryView_FromObject(buffer.as_ptr()))? };
85
86 Ok(view)
87 }
88}
89
90#[pymethods]
91impl Buffer {
92 unsafe fn __getbuffer__(
93 slf: PyRefMut<Self>,
94 view: *mut ffi::Py_buffer,
95 flags: c_int,
96 ) -> PyResult<()> {
97 let bytes = slf.0.as_slice();
98 let ret = ffi::PyBuffer_FillInfo(
99 view,
100 slf.as_ptr() as *mut _,
101 bytes.as_ptr() as *mut _,
102 bytes.len().try_into().unwrap(),
103 1, flags,
105 );
106 if ret == -1 {
107 return Err(PyErr::fetch(slf.py()));
108 }
109 Ok(())
110 }
111}