1use crate::metadata::{IoTypeMetadataKind, MAX_METADATA_CAPACITY, concat_metadata_sources};
2use crate::trivial_type::TrivialType;
3use core::fmt;
4#[cfg(feature = "scale-codec")]
5use parity_scale_codec::{Decode, Encode, EncodeLike, MaxEncodedLen, Output};
6#[cfg(feature = "serde")]
7use serde::{Deserialize, Serialize, Serializer};
8
9#[derive(Debug, Default, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
16#[cfg_attr(feature = "scale-codec", derive(Decode, MaxEncodedLen))]
17#[cfg_attr(feature = "serde", derive(Deserialize))]
18#[cfg_attr(feature = "serde", serde(transparent))]
19#[repr(C, packed)]
20pub struct Unaligned<Data>(Data)
21where
22 Data: TrivialType;
23
24impl<Data> From<Data> for Unaligned<Data>
25where
26 Data: TrivialType,
27{
28 #[inline(always)]
29 fn from(value: Data) -> Self {
30 Self(value)
31 }
32}
33
34impl<Data> fmt::Display for Unaligned<Data>
35where
36 Data: TrivialType + fmt::Display,
37{
38 #[inline]
39 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40 let inner = self.0;
41 inner.fmt(f)
42 }
43}
44
45unsafe impl<Data> TrivialType for Unaligned<Data>
47where
48 Data: TrivialType,
49{
50 const METADATA: &[u8] = {
51 const fn metadata(inner_metadata: &[u8]) -> ([u8; MAX_METADATA_CAPACITY], usize) {
52 concat_metadata_sources(&[&[IoTypeMetadataKind::Unaligned as u8], inner_metadata])
53 }
54
55 metadata(Data::METADATA)
57 .0
58 .split_at(metadata(Data::METADATA).1)
59 .0
60 };
61}
62
63#[cfg(feature = "scale-codec")]
64impl<Data> Encode for Unaligned<Data>
65where
66 Data: TrivialType + Encode,
67{
68 #[inline(always)]
69 fn size_hint(&self) -> usize {
70 let inner = self.0;
71 inner.size_hint()
72 }
73
74 #[inline(always)]
75 fn encode_to<T: Output + ?Sized>(&self, dest: &mut T) {
76 let inner = self.0;
77 inner.encode_to(dest)
78 }
79
80 #[inline(always)]
81 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
82 let inner = self.0;
83 inner.using_encoded(f)
84 }
85}
86
87#[cfg(feature = "scale-codec")]
88impl<Data> EncodeLike for Unaligned<Data> where Data: TrivialType + Encode {}
89
90#[cfg(feature = "serde")]
91impl<Data> Serialize for Unaligned<Data>
92where
93 Data: TrivialType + Serialize,
94{
95 #[inline(always)]
96 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
97 where
98 S: Serializer,
99 {
100 let inner = self.0;
101 inner.serialize(serializer)
102 }
103}
104
105impl<Data> Unaligned<Data>
106where
107 Data: TrivialType,
108{
109 #[inline(always)]
111 pub const fn new(inner: Data) -> Self {
112 Self(inner)
113 }
114
115 #[inline(always)]
117 pub const fn as_inner(&self) -> Data {
118 self.0
119 }
120
121 pub const fn replace(&mut self, value: Data) {
123 self.0 = value;
124 }
125}