use super::*;
pub type ZyanStringFlags = u8;
#[derive(Debug)]
#[repr(C)]
pub struct ZyanString {
flags: ZyanStringFlags,
vector: ZyanVector,
}
impl ZyanString {
#[inline]
pub fn new(buffer: &mut [u8]) -> Result<Self> {
Self::new_ptr(buffer.as_mut_ptr(), buffer.len())
}
#[inline]
pub fn new_ptr(buffer: *mut u8, capacity: usize) -> Result<Self> {
unsafe {
let mut string = MaybeUninit::uninit();
ZyanStringInitCustomBuffer(string.as_mut_ptr(), buffer as *mut c_char, capacity)
.as_result()?;
Ok(string.assume_init())
}
}
#[inline]
pub fn append<S: AsRef<str> + ?Sized>(&mut self, s: &S) -> Result {
unsafe {
let bytes = s.as_ref().as_bytes();
let view = ZyanStringView::new(bytes)?;
ZyanStringAppend(self, &view).into()
}
}
}
impl fmt::Write for ZyanString {
fn write_str(&mut self, s: &str) -> fmt::Result {
self.append(s).map_err(|_| fmt::Error)
}
}
#[derive(Debug)]
#[repr(C)]
pub struct ZyanStringView {
string: ZyanString,
}
impl ZyanStringView {
#[inline]
pub fn new(buffer: &[u8]) -> Result<Self> {
unsafe {
let mut view = MaybeUninit::uninit();
ZyanStringViewInsideBufferEx(
view.as_mut_ptr(),
buffer.as_ptr() as *const c_char,
buffer.len(),
)
.as_result()?;
Ok(view.assume_init())
}
}
}
#[derive(Debug)]
#[repr(C)]
struct ZyanVector {
allocator: *mut c_void,
growth_factor: f32,
shrink_threshold: f32,
size: usize,
capacity: usize,
element_size: usize,
destructor: *mut c_void,
data: *mut c_void,
}
extern "C" {
pub fn ZyanStringInitCustomBuffer(
string: *mut ZyanString,
buffer: *mut c_char,
capacity: usize,
) -> Status;
pub fn ZyanStringAppend(destination: *mut ZyanString, source: *const ZyanStringView) -> Status;
pub fn ZyanStringDestroy(string: *mut ZyanString) -> Status;
pub fn ZyanStringViewInsideBufferEx(
view: *mut ZyanStringView,
buffer: *const c_char,
length: usize,
) -> Status;
}