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