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>
49where
50 Data: TrivialType,
51{
52 const METADATA: &[u8] = {
53 const fn metadata(inner_metadata: &[u8]) -> ([u8; MAX_METADATA_CAPACITY], usize) {
54 concat_metadata_sources(&[&[IoTypeMetadataKind::Unaligned as u8], inner_metadata])
55 }
56
57 metadata(Data::METADATA)
59 .0
60 .split_at(metadata(Data::METADATA).1)
61 .0
62 };
63}
64
65#[cfg(feature = "scale-codec")]
66impl<Data> Encode for Unaligned<Data>
67where
68 Data: TrivialType + Encode,
69{
70 #[inline(always)]
71 fn size_hint(&self) -> usize {
72 let inner = self.0;
73 inner.size_hint()
74 }
75
76 #[inline(always)]
77 fn encode_to<T: Output + ?Sized>(&self, dest: &mut T) {
78 let inner = self.0;
79 inner.encode_to(dest)
80 }
81
82 #[inline(always)]
83 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
84 let inner = self.0;
85 inner.using_encoded(f)
86 }
87}
88
89#[cfg(feature = "scale-codec")]
90impl<Data> EncodeLike for Unaligned<Data> where Data: TrivialType + Encode {}
91
92#[cfg(feature = "serde")]
93impl<Data> Serialize for Unaligned<Data>
94where
95 Data: TrivialType + Serialize,
96{
97 #[inline(always)]
98 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
99 where
100 S: Serializer,
101 {
102 let inner = self.0;
103 inner.serialize(serializer)
104 }
105}
106
107impl<Data> Unaligned<Data>
108where
109 Data: TrivialType,
110{
111 #[inline(always)]
113 pub const fn new(inner: Data) -> Self {
114 Self(inner)
115 }
116
117 #[inline(always)]
119 pub const fn as_inner(&self) -> Data {
120 self.0
121 }
122
123 pub const fn replace(&mut self, value: Data) {
125 self.0 = value;
126 }
127}