1use crate::{
16 Packed,
17 StorageLayout,
18};
19use ink_metadata::layout::{
20 ArrayLayout,
21 Discriminant,
22 EnumLayout,
23 FieldLayout,
24 Layout,
25 LayoutKey,
26 LeafLayout,
27 StructLayout,
28};
29use ink_prelude::{
30 boxed::Box,
31 collections::{
32 BTreeMap,
33 BTreeSet,
34 VecDeque,
35 },
36 string::String,
37 vec::Vec,
38};
39use ink_primitives::{
40 AccountId,
41 Address,
42 Hash,
43 Key,
44 H160,
45 H256,
46 U256,
47};
48use scale_info::TypeInfo;
49
50macro_rules! impl_storage_layout_for_primitives {
51 ( $($name:ty),* $(,)? ) => {
52 $(
53 impl StorageLayout for $name {
54 fn layout(key: &Key) -> Layout {
55 Layout::Leaf(LeafLayout::from_key::<$name>(LayoutKey::from(key)))
56 }
57 }
58 )*
59 };
60}
61#[rustfmt::skip]
62impl_storage_layout_for_primitives!(
63 AccountId, Address, Hash, String,
64 H160, H256, U256,
65 bool, char, (),
66 u8, u16, u32, u64, u128,
67 i8, i16, i32, i64, i128,
68);
69
70macro_rules! impl_layout_for_tuple {
71 ( $(($frag:ident, $id:literal)),* $(,)? ) => {
72 const _: () = {
73 const TUPLE_NAME: &'static str = stringify!(($($frag),*));
75
76 impl<$($frag),*> StorageLayout for ($($frag),* ,)
77 where
78 $(
79 $frag: StorageLayout,
80 )*
81 {
82 fn layout(key: &Key) -> Layout {
83 Layout::Struct(
84 StructLayout::new(
85 TUPLE_NAME,
86 [
87 $(
88 FieldLayout::new(
89 ::core::stringify!($id),
90 <$frag as StorageLayout>::layout(key)
91 ),
92 )*
93 ]
94 )
95 )
96 }
97 }
98 };
99 }
100}
101
102impl_layout_for_tuple!((A, 0));
103impl_layout_for_tuple!((A, 0), (B, 1));
104impl_layout_for_tuple!((A, 0), (B, 1), (C, 2));
105impl_layout_for_tuple!((A, 0), (B, 1), (C, 2), (D, 3));
106impl_layout_for_tuple!((A, 0), (B, 1), (C, 2), (D, 3), (E, 4));
107impl_layout_for_tuple!((A, 0), (B, 1), (C, 2), (D, 3), (E, 4), (F, 5));
108impl_layout_for_tuple!((A, 0), (B, 1), (C, 2), (D, 3), (E, 4), (F, 5), (G, 6));
109impl_layout_for_tuple!(
110 (A, 0),
111 (B, 1),
112 (C, 2),
113 (D, 3),
114 (E, 4),
115 (F, 5),
116 (G, 6),
117 (H, 7)
118);
119impl_layout_for_tuple!(
120 (A, 0),
121 (B, 1),
122 (C, 2),
123 (D, 3),
124 (E, 4),
125 (F, 5),
126 (G, 6),
127 (H, 7),
128 (I, 8)
129);
130impl_layout_for_tuple!(
131 (A, 0),
132 (B, 1),
133 (C, 2),
134 (D, 3),
135 (E, 4),
136 (F, 5),
137 (G, 6),
138 (H, 7),
139 (I, 8),
140 (J, 9)
141);
142
143impl<T, const N: usize> StorageLayout for [T; N]
144where
145 T: StorageLayout + Packed,
146{
147 fn layout(key: &Key) -> Layout {
148 let len: u32 = N as u32;
149 Layout::Array(ArrayLayout::new(
151 LayoutKey::from(key),
152 len,
153 <T as StorageLayout>::layout(key),
154 ))
155 }
156}
157
158impl<T> StorageLayout for Box<T>
159where
160 T: StorageLayout,
161{
162 fn layout(key: &Key) -> Layout {
163 <T as StorageLayout>::layout(key)
164 }
165}
166
167impl<T> StorageLayout for Option<T>
168where
169 T: StorageLayout,
170{
171 fn layout(key: &Key) -> Layout {
172 Layout::Enum(EnumLayout::new(
173 "Option",
174 key,
175 [
176 (Discriminant::from(0), StructLayout::new("None", Vec::new())),
177 (
178 Discriminant::from(1),
179 StructLayout::new(
180 "Some",
181 [FieldLayout::new("0", <T as StorageLayout>::layout(key))],
182 ),
183 ),
184 ],
185 ))
186 }
187}
188
189impl<T, E> StorageLayout for Result<T, E>
190where
191 T: StorageLayout,
192 E: StorageLayout,
193{
194 fn layout(key: &Key) -> Layout {
195 Layout::Enum(EnumLayout::new(
196 "Result",
197 *key,
198 [
199 (
200 Discriminant::from(0),
201 StructLayout::new(
202 "Ok",
203 [FieldLayout::new("0", <T as StorageLayout>::layout(key))],
204 ),
205 ),
206 (
207 Discriminant::from(1),
208 StructLayout::new(
209 "Err",
210 [FieldLayout::new("1", <E as StorageLayout>::layout(key))],
211 ),
212 ),
213 ],
214 ))
215 }
216}
217
218impl<T> StorageLayout for Vec<T>
219where
220 T: TypeInfo + 'static + Packed,
221{
222 fn layout(key: &Key) -> Layout {
223 Layout::Leaf(LeafLayout::from_key::<Self>(LayoutKey::from(key)))
224 }
225}
226
227impl<K, V> StorageLayout for BTreeMap<K, V>
228where
229 K: TypeInfo + 'static + Packed,
230 V: TypeInfo + 'static + Packed,
231{
232 fn layout(key: &Key) -> Layout {
233 Layout::Leaf(LeafLayout::from_key::<Self>(LayoutKey::from(key)))
234 }
235}
236
237impl<T> StorageLayout for BTreeSet<T>
238where
239 T: TypeInfo + 'static + Packed,
240{
241 fn layout(key: &Key) -> Layout {
242 Layout::Leaf(LeafLayout::from_key::<Self>(LayoutKey::from(key)))
243 }
244}
245
246impl<T> StorageLayout for VecDeque<T>
247where
248 T: TypeInfo + 'static + Packed,
249{
250 fn layout(key: &Key) -> Layout {
251 Layout::Leaf(LeafLayout::from_key::<Self>(LayoutKey::from(key)))
252 }
253}