use crate::inventory::{Inventory, TypeId};
use crate::lang::meta::{Docs, Visibility, common_or_module_emission};
use crate::lang::types::{Type, TypeInfo, TypeKind, TypePattern, WireIO};
use crate::wire::SerializationError;
use std::io::{Read, Write};
use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};
use std::ptr::{null, null_mut};
#[repr(C)]
pub struct Slice<'a, T> {
data: *const T,
len: u64,
_phantom: PhantomData<&'a T>,
}
impl<T> Copy for Slice<'_, T> {}
impl<T> Clone for Slice<'_, T> {
fn clone(&self) -> Self {
*self
}
}
impl<T> Default for Slice<'_, T> {
fn default() -> Self {
const {
assert!(size_of::<Self>() == 16);
}
Self { data: null(), len: 0, _phantom: PhantomData }
}
}
impl<'a, T> Slice<'a, T> {
pub const fn from_slice(slice: &'a [T]) -> Self {
Slice { data: slice.as_ptr(), len: slice.len() as u64, _phantom: PhantomData }
}
#[must_use]
#[allow(clippy::cast_possible_truncation)]
pub fn as_slice(&self) -> &'a [T] {
if self.data.is_null() {
&[]
} else {
unsafe { std::slice::from_raw_parts(self.data, self.len as usize) }
}
}
}
impl<'a, T> From<&'a [T]> for Slice<'a, T> {
fn from(slice: &'a [T]) -> Self {
Self::from_slice(slice)
}
}
impl<T> Slice<'_, T>
where
T: 'static,
{
#[must_use]
pub const fn empty() -> Self {
let x: &'static [T] = &[];
Self::from_slice(x)
}
}
impl<T> Deref for Slice<'_, T> {
type Target = [T];
fn deref(&self) -> &Self::Target {
self.as_slice()
}
}
unsafe impl<T: TypeInfo> TypeInfo for Slice<'_, T> {
const WIRE_SAFE: bool = false;
const RAW_SAFE: bool = T::RAW_SAFE;
const ASYNC_SAFE: bool = false;
const SERVICE_SAFE: bool = false;
const SERVICE_CTOR_SAFE: bool = false;
fn id() -> TypeId {
TypeId::new(0xD77995219511CB31F7AB1D5D8F2D8A22).derive_id(T::id())
}
fn kind() -> TypeKind {
TypeKind::TypePattern(TypePattern::Slice(T::id()))
}
fn ty() -> Type {
let t = T::ty();
let emission = common_or_module_emission(&[t.emission]);
Type { name: format!("Slice<{}>", t.name), visibility: Visibility::Public, docs: Docs::empty(), emission, kind: Self::kind() }
}
fn register(inventory: &mut impl Inventory) {
T::register(inventory);
inventory.register_type(Self::id(), Self::ty());
}
}
unsafe impl<T: WireIO> WireIO for Slice<'_, T> {
fn write(&self, _: &mut impl Write) -> Result<(), SerializationError> {
todo!()
}
fn read(_: &mut impl Read) -> Result<Self, SerializationError> {
todo!()
}
fn live_size(&self) -> usize {
todo!()
}
}
#[repr(C)]
pub struct SliceMut<'a, T> {
data: *mut T,
len: u64,
_phantom: PhantomData<&'a mut T>,
}
impl<T> Default for SliceMut<'_, T> {
fn default() -> Self {
Self { data: null_mut(), len: 0, _phantom: PhantomData }
}
}
impl<'a, T> SliceMut<'a, T> {
pub fn from_slice(slice: &'a mut [T]) -> Self {
SliceMut { data: slice.as_mut_ptr(), len: slice.len() as u64, _phantom: PhantomData }
}
#[allow(clippy::cast_possible_truncation)]
pub fn as_slice_mut(&mut self) -> &'a mut [T] {
if self.data.is_null() {
&mut []
} else {
unsafe { std::slice::from_raw_parts_mut(self.data, self.len as usize) }
}
}
#[must_use]
#[allow(clippy::cast_possible_truncation)]
pub fn as_slice(&self) -> &'a [T] {
if self.data.is_null() {
&[]
} else {
unsafe { std::slice::from_raw_parts(self.data, self.len as usize) }
}
}
}
impl<T> SliceMut<'_, T>
where
T: 'static,
{
#[must_use]
pub fn empty() -> Self {
let x: &'static mut [T] = &mut [];
Self::from_slice(x)
}
}
impl<'a, T> From<&'a mut [T]> for SliceMut<'a, T> {
fn from(slice: &'a mut [T]) -> Self {
Self::from_slice(slice)
}
}
impl<T> Deref for SliceMut<'_, T> {
type Target = [T];
fn deref(&self) -> &Self::Target {
self.as_slice()
}
}
impl<T> DerefMut for SliceMut<'_, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.as_slice_mut()
}
}
unsafe impl<T: TypeInfo> TypeInfo for SliceMut<'_, T> {
const WIRE_SAFE: bool = false;
const RAW_SAFE: bool = T::RAW_SAFE;
const ASYNC_SAFE: bool = false;
const SERVICE_SAFE: bool = false;
const SERVICE_CTOR_SAFE: bool = false;
fn id() -> TypeId {
TypeId::new(0xB4DB1DCC839538A76319E0F537203502).derive_id(T::id())
}
fn kind() -> TypeKind {
TypeKind::TypePattern(TypePattern::SliceMut(T::id()))
}
fn ty() -> Type {
let t = T::ty();
let emission = common_or_module_emission(&[t.emission]);
Type { name: format!("SliceMut<{}>", t.name), visibility: Visibility::Public, docs: Docs::empty(), emission, kind: Self::kind() }
}
fn register(inventory: &mut impl Inventory) {
T::register(inventory);
inventory.register_type(Self::id(), Self::ty());
}
}
unsafe impl<T: WireIO> WireIO for SliceMut<'_, T> {
fn write(&self, _: &mut impl Write) -> Result<(), SerializationError> {
todo!()
}
fn read(_: &mut impl Read) -> Result<Self, SerializationError> {
todo!()
}
fn live_size(&self) -> usize {
todo!()
}
}