use std::{alloc::{self, Layout}, ops::Add};
#[derive(Debug, Clone, Copy)]
pub struct ObjString {
pub ptr: *mut char,
pub length: usize,
}
impl From<String> for ObjString {
fn from(value: String) -> Self {
unsafe {
let layout = Layout::array::<char>(value.len()).unwrap();
let ptr = alloc::alloc(layout) as *mut char;
Self {
ptr,
length: value.len(),
}
}
}
}
impl From<ObjString> for String {
fn from(value: ObjString) -> Self {
unsafe {
String::from_raw_parts(value.ptr as *mut u8, value.length, value.length)
}
}
}
impl ToString for ObjString {
fn to_string(&self) -> String {
String::from(*self)
}
}
impl Add for ObjString {
type Output = Self;
fn add(self, other: Self) -> Self {
let layout = Layout::array::<char>(self.length + other.length).unwrap();
unsafe {
let ptr = alloc::alloc(layout) as *mut char;
self.ptr.copy_to(ptr, self.length);
other.ptr.copy_to(ptr.offset(self.length as isize), other.length);
self.free();
other.free();
Self {
ptr,
length: self.length + other.length,
}
}
}
}
impl ObjString {
pub fn free(self) {
if self.length != 0 {
let layout = Layout::array::<char>(self.length).unwrap();
unsafe {
alloc::dealloc(self.ptr as *mut u8, layout)
}
}
}
}