use osom_lib_alloc::traits::Allocator;
use osom_lib_arc::carc_array::CArcArrayBuilder;
use osom_lib_primitives::length::Length;
use osom_lib_reprc::macros::reprc;
use super::{SharedString, SharedStringError};
#[reprc]
#[repr(transparent)]
#[must_use]
pub struct SharedStringBuilder<TAllocator: Allocator> {
internal: CArcArrayBuilder<u8, TAllocator>,
}
impl<TAllocator: Allocator> SharedStringBuilder<TAllocator> {
#[inline]
pub fn new() -> Result<Self, SharedStringError>
where
TAllocator: Default,
{
Self::with_capacity_and_allocator(Length::ZERO, TAllocator::default())
}
#[inline]
pub fn with_capacity(capacity: Length) -> Result<Self, SharedStringError>
where
TAllocator: Default,
{
Self::with_capacity_and_allocator(capacity, TAllocator::default())
}
#[inline]
pub fn with_allocator(allocator: TAllocator) -> Result<Self, SharedStringError> {
Self::with_capacity_and_allocator(Length::ZERO, allocator)
}
#[inline]
pub fn with_capacity_and_allocator(capacity: Length, allocator: TAllocator) -> Result<Self, SharedStringError> {
let internal = CArcArrayBuilder::with_capacity_and_allocator(capacity + 1, allocator)?;
Ok(Self { internal })
}
#[inline]
pub fn try_push(&mut self, text: &str) -> Result<(), SharedStringError> {
self.internal
.try_push_slice(text.as_bytes())
.map_err(SharedStringError::from)
}
pub fn shrink_to_fit(&mut self) -> Result<(), SharedStringError> {
self.internal.shrink_to_fit().map_err(SharedStringError::from)
}
pub fn build(self) -> Result<SharedString<TAllocator>, SharedStringError> {
let mut internal = unsafe { (&raw const self.internal).read() };
core::mem::forget(self);
internal.try_push_slice(b"\0")?;
internal.shrink_to_fit()?;
let result = SharedString::from_internal(internal.build());
Ok(result)
}
}