pub mod impls;
pub mod init;
#[cfg(all(feature = "test_helpers", not(target_os = "solana")))]
mod test_helpers;
#[cfg(all(test, feature = "test_helpers"))]
mod tests;
pub mod wrapper;
use std::ops::Range;
pub use star_frame_proc::{unsized_impl, unsized_type};
#[cfg(all(feature = "test_helpers", not(target_os = "solana")))]
pub use test_helpers::*;
use crate::{ensure, ErrorCode, Result};
pub unsafe trait UnsizedTypePtr {
type UnsizedType: UnsizedType + ?Sized;
fn check_pointers(&self, range: &Range<usize>, cursor: &mut usize) -> bool;
}
pub unsafe trait UnsizedType: 'static {
type Ptr: UnsizedTypePtr;
type Owned;
const ZST_STATUS: bool;
unsafe fn get_ptr(data: &mut *mut [u8]) -> Result<Self::Ptr>;
fn start_ptr(m: &Self::Ptr) -> *mut ();
fn data_len(m: &Self::Ptr) -> usize;
fn owned(data: &[u8]) -> Result<Self::Owned> {
let data: *const [u8] = data;
Self::owned_from_ptr(&unsafe { Self::get_ptr(&mut data.cast_mut()) }?)
}
fn owned_from_ptr(r: &Self::Ptr) -> Result<Self::Owned>;
#[allow(unused_variables)]
unsafe fn resize_notification(
self_mut: &mut Self::Ptr,
source_ptr: *const (),
change: isize,
) -> Result<()>;
}
#[doc(hidden)]
mod sealed {
pub trait Sealed {}
impl Sealed for *mut [u8] {}
}
pub trait RawSliceAdvance: Sized + sealed::Sealed {
fn try_advance(&mut self, advance: usize) -> Result<Self>;
}
impl RawSliceAdvance for *mut [u8] {
#[inline]
fn try_advance(&mut self, advance: usize) -> Result<Self> {
let len = self.len();
ensure!(
advance <= len,
ErrorCode::RawSliceAdvance,
"Tried to advance a raw slice by {advance} bytes, but the slice only has {len} bytes remaining"
);
let to_return = core::ptr::slice_from_raw_parts_mut(self.cast::<u8>(), advance);
*self = core::ptr::slice_from_raw_parts_mut(
self.cast::<u8>().wrapping_add(advance),
len - advance,
);
Ok(to_return)
}
}
pub trait FromOwned: UnsizedType {
fn byte_size(owned: &Self::Owned) -> usize;
fn from_owned(owned: Self::Owned, bytes: &mut &mut [u8]) -> Result<usize>;
}
#[cfg(doctest)]
struct TestUnsizedZst;
#[allow(unused)]
#[cfg(miri)]
extern "Rust" {
fn miri_static_root(ptr: *const ());
}
pub mod prelude {
use super::*;
pub use super::{unsized_impl, unsized_type, UnsizedType};
pub use impls::prelude::*;
pub use init::DefaultInit;
pub use wrapper::{ExclusiveRecurse, ExclusiveWrapper, ExclusiveWrapperTop};
}