use crate::metadata::{IoTypeMetadataKind, MAX_METADATA_CAPACITY, concat_metadata_sources};
use crate::trivial_type::TrivialType;
use core::fmt;
#[cfg(feature = "scale-codec")]
use parity_scale_codec::{Decode, Encode, EncodeLike, MaxEncodedLen, Output};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize, Serializer};
#[derive(Debug, Default, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "scale-codec", derive(Decode, MaxEncodedLen))]
#[cfg_attr(feature = "serde", derive(Deserialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
#[repr(C, packed)]
pub struct Unaligned<Data>(Data)
where
Data: TrivialType;
impl<Data> const From<Data> for Unaligned<Data>
where
Data: TrivialType,
{
#[inline(always)]
fn from(value: Data) -> Self {
Self(value)
}
}
impl<Data> fmt::Display for Unaligned<Data>
where
Data: TrivialType + fmt::Display,
{
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let inner = self.0;
inner.fmt(f)
}
}
unsafe impl<Data> TrivialType for Unaligned<Data>
where
Data: TrivialType,
{
const METADATA: &[u8] = {
const fn metadata(inner_metadata: &[u8]) -> ([u8; MAX_METADATA_CAPACITY], usize) {
concat_metadata_sources(&[&[IoTypeMetadataKind::Unaligned as u8], inner_metadata])
}
metadata(Data::METADATA)
.0
.split_at(metadata(Data::METADATA).1)
.0
};
}
#[cfg(feature = "scale-codec")]
impl<Data> Encode for Unaligned<Data>
where
Data: TrivialType + Encode,
{
#[inline(always)]
fn size_hint(&self) -> usize {
let inner = self.0;
inner.size_hint()
}
#[inline(always)]
fn encode_to<T: Output + ?Sized>(&self, dest: &mut T) {
let inner = self.0;
inner.encode_to(dest)
}
#[inline(always)]
fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
let inner = self.0;
inner.using_encoded(f)
}
}
#[cfg(feature = "scale-codec")]
impl<Data> EncodeLike for Unaligned<Data> where Data: TrivialType + Encode {}
#[cfg(feature = "serde")]
impl<Data> Serialize for Unaligned<Data>
where
Data: TrivialType + Serialize,
{
#[inline(always)]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let inner = self.0;
inner.serialize(serializer)
}
}
impl<Data> Unaligned<Data>
where
Data: TrivialType,
{
#[inline(always)]
pub const fn new(inner: Data) -> Self {
Self(inner)
}
#[inline(always)]
pub const fn as_inner(&self) -> Data {
self.0
}
pub const fn replace(&mut self, value: Data) {
self.0 = value;
}
}