use core::mem::size_of;
#[cfg(feature = "std")]
use std::io::{self, Write};
use bytemuck::{bytes_of, Pod, Zeroable};
#[cfg(feature = "std")]
use crate::std140::Writer;
pub unsafe trait Std140: Copy + Zeroable + Pod {
const ALIGNMENT: usize;
fn as_bytes(&self) -> &[u8] {
bytes_of(self)
}
}
pub trait AsStd140 {
type Output: Std140;
fn as_std140(&self) -> Self::Output;
fn std140_size_static() -> usize {
size_of::<Self::Output>()
}
fn from_std140(val: Self::Output) -> Self;
}
impl<T> AsStd140 for T
where
T: Std140,
{
type Output = Self;
fn as_std140(&self) -> Self {
*self
}
fn from_std140(x: Self) -> Self {
x
}
}
#[cfg(feature = "std")]
pub trait WriteStd140 {
fn write_std140<W: Write>(&self, writer: &mut Writer<W>) -> io::Result<usize>;
fn std140_size(&self) -> usize {
let mut writer = Writer::new(io::sink());
self.write_std140(&mut writer).unwrap();
writer.len()
}
}
#[cfg(feature = "std")]
impl<T> WriteStd140 for T
where
T: AsStd140,
{
fn write_std140<W: Write>(&self, writer: &mut Writer<W>) -> io::Result<usize> {
writer.write_std140(&self.as_std140())
}
fn std140_size(&self) -> usize {
size_of::<<Self as AsStd140>::Output>()
}
}
#[cfg(feature = "std")]
impl<T> WriteStd140 for [T]
where
T: WriteStd140,
{
fn write_std140<W: Write>(&self, writer: &mut Writer<W>) -> io::Result<usize> {
let mut offset = writer.len();
let mut iter = self.iter();
if let Some(item) = iter.next() {
offset = item.write_std140(writer)?;
}
for item in iter {
item.write_std140(writer)?;
}
Ok(offset)
}
fn std140_size(&self) -> usize {
let mut writer = Writer::new(io::sink());
self.write_std140(&mut writer).unwrap();
writer.len()
}
}