use crate::inventory::Inventory;
use crate::lang::meta::{Docs, Emission, Visibility};
use crate::lang::types::wire::WireIO;
use crate::lang::types::{Type, TypeId, TypeInfo, TypeKind};
use crate::wire::SerializationError;
use std::io::{Read, Write};
use std::mem::MaybeUninit;
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Array {
pub ty: TypeId,
pub len: usize,
}
unsafe impl<T, const N: usize> TypeInfo for [T; N]
where
T: TypeInfo + Copy,
{
const WIRE_SAFE: bool = T::WIRE_SAFE;
const RAW_SAFE: bool = T::RAW_SAFE;
const ASYNC_SAFE: bool = T::ASYNC_SAFE;
const SERVICE_SAFE: bool = false;
const SERVICE_CTOR_SAFE: bool = false;
fn id() -> TypeId {
T::id().derive(0x06A3676E231857123975EA87924CA277).derive(N as u128)
}
fn kind() -> TypeKind {
TypeKind::Array(Array { ty: T::id(), len: N })
}
fn ty() -> Type {
Type { emission: Emission::Builtin, docs: Docs::empty(), visibility: Visibility::Public, name: format!("[{}; {N}]", T::ty().name), kind: Self::kind() }
}
fn register(inventory: &mut impl Inventory) {
T::register(inventory);
inventory.register_type(Self::id(), Self::ty());
}
}
unsafe impl<T, const N: usize> WireIO for [T; N]
where
T: WireIO + Copy,
{
fn write(&self, out: &mut impl Write) -> Result<(), SerializationError> {
for x in self {
x.write(out)?;
}
Ok(())
}
fn read(input: &mut impl Read) -> Result<Self, SerializationError> {
let mut rval = [MaybeUninit::uninit(); N];
for x in &mut rval {
x.write(T::read(input)?);
}
Ok(unsafe { std::mem::transmute_copy(&rval) })
}
fn live_size(&self) -> usize {
self.iter().map(WireIO::live_size).sum()
}
}