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