Skip to content

Commit e8d3e97

Browse files
cleanup and refactor the code
Signed-off-by: Valentyn Faychuk <valy@faychuk.com>
1 parent 7056566 commit e8d3e97

4 files changed

Lines changed: 132 additions & 151 deletions

File tree

contract_samples/rust/build_and_validate.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,16 @@ cargo build -p amadeus-sdk --example counter --target wasm32-unknown-unknown --r
88
cargo build -p amadeus-sdk --example deposit --target wasm32-unknown-unknown --release
99
cargo build -p amadeus-sdk --example coin --target wasm32-unknown-unknown --release
1010
cargo build -p amadeus-sdk --example nft --target wasm32-unknown-unknown --release
11+
cargo build -p amadeus-sdk --example showcase --target wasm32-unknown-unknown --release
1112

1213
wasm-opt -Oz --enable-bulk-memory target/wasm32-unknown-unknown/release/examples/counter.wasm -o counter.wasm
1314
wasm-opt -Oz --enable-bulk-memory target/wasm32-unknown-unknown/release/examples/deposit.wasm -o deposit.wasm
1415
wasm-opt -Oz --enable-bulk-memory target/wasm32-unknown-unknown/release/examples/coin.wasm -o coin.wasm
1516
wasm-opt -Oz --enable-bulk-memory target/wasm32-unknown-unknown/release/examples/nft.wasm -o nft.wasm
17+
wasm-opt -Oz --enable-bulk-memory target/wasm32-unknown-unknown/release/examples/showcase.wasm -o showcase.wasm
1618

1719
curl -X POST -H "Content-Type: application/octet-stream" --data-binary @counter.wasm https://mainnet-rpc.ama.one/api/contract/validate
1820
curl -X POST -H "Content-Type: application/octet-stream" --data-binary @deposit.wasm https://mainnet-rpc.ama.one/api/contract/validate
1921
curl -X POST -H "Content-Type: application/octet-stream" --data-binary @coin.wasm https://mainnet-rpc.ama.one/api/contract/validate
2022
curl -X POST -H "Content-Type: application/octet-stream" --data-binary @nft.wasm https://mainnet-rpc.ama.one/api/contract/validate
23+
curl -X POST -H "Content-Type: application/octet-stream" --data-binary @showcase.wasm https://mainnet-rpc.ama.one/api/contract/validate

contract_samples/rust/examples/showcase.rs

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,15 @@ struct TournamentInfo {
1818
#[flat] prize_pool: u64,
1919
}
2020

21+
type PlayerWinsMap = MapFlat<String, u32>;
22+
type MatchesMap = Map<u64, Match>;
23+
type PlayersMap = Map<String, MatchesMap>;
24+
2125
#[contract_state]
2226
struct Leaderboard {
2327
#[flat] total_matches: i32,
24-
player_wins: Map<String, u32>,
25-
players: MapNested<String, MapNested<u64, Match>>,
28+
player_wins: PlayerWinsMap,
29+
players: PlayersMap,
2630
tournament: TournamentInfo,
2731
}
2832

@@ -36,38 +40,35 @@ impl Leaderboard {
3640
(*self.total_matches).to_string().into_bytes()
3741
}
3842

39-
pub fn record_match(&mut self, player: String, match_id: Vec<u8>, score: Vec<u8>, opponent: String) {
40-
let match_id_u64 = u64::from_bytes(match_id);
43+
pub fn record_match(&mut self, player: String, match_id: u64, score: u16, opponent: String) {
4144
self.players.with_mut(player, |matches| {
42-
matches.with_mut(match_id_u64, |m| {
43-
*m.score = u16::from_bytes(score);
45+
matches.with_mut(match_id, |m| {
46+
*m.score = score;
4447
*m.opponent = opponent;
4548
});
4649
});
4750
*self.total_matches += 1;
4851
}
4952

50-
pub fn get_match_score(&mut self, player: String, match_id: Vec<u8>) -> Vec<u8> {
51-
let match_id_u64 = u64::from_bytes(match_id);
53+
pub fn get_match_score(&mut self, player: String, match_id: u64) -> Vec<u8> {
5254
self.players.with_mut(player, |matches| {
53-
matches.with_mut(match_id_u64, |m| {
55+
matches.with_mut(match_id, |m| {
5456
(*m.score).to_string().into_bytes()
5557
})
5658
})
5759
}
5860

59-
pub fn get_match_opponent(&mut self, player: String, match_id: Vec<u8>) -> String {
60-
let match_id_u64 = u64::from_bytes(match_id);
61+
pub fn get_match_opponent(&mut self, player: String, match_id: u64) -> String {
6162
self.players.with_mut(player, |matches| {
62-
matches.with_mut(match_id_u64, |m| {
63+
matches.with_mut(match_id, |m| {
6364
(*m.opponent).clone()
6465
})
6566
})
6667
}
6768

68-
pub fn set_tournament_info(&mut self, name: String, prize_pool: Vec<u8>) {
69+
pub fn set_tournament_info(&mut self, name: String, prize_pool: u64) {
6970
*self.tournament.name = name;
70-
*self.tournament.prize_pool = u64::from_bytes(prize_pool);
71+
*self.tournament.prize_pool = prize_pool;
7172
}
7273

7374
pub fn get_tournament_name(&mut self) -> String {
@@ -94,7 +95,7 @@ impl Leaderboard {
9495
}
9596
}
9697

97-
pub fn set_player_wins(&mut self, player: String, wins: Vec<u8>) {
98-
self.player_wins.insert(player, u32::from_bytes(wins));
98+
pub fn set_player_wins(&mut self, player: String, wins: u32) {
99+
self.player_wins.insert(player, wins);
99100
}
100101
}

contract_samples/rust/sdk-macros/src/lib.rs

Lines changed: 65 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,6 @@ pub fn contract_state(_attr: TokenStream, item: TokenStream) -> TokenStream {
1717
f.attrs.iter().any(|attr| attr.path().is_ident("flat"))
1818
};
1919

20-
let is_map = |f: &syn::Field| -> bool {
21-
if let Type::Path(type_path) = &f.ty {
22-
if let Some(segment) = type_path.path.segments.first() {
23-
return segment.ident == "Map";
24-
}
25-
}
26-
false
27-
};
28-
29-
let is_map_nested = |f: &syn::Field| -> bool {
30-
if let Type::Path(type_path) = &f.ty {
31-
if let Some(segment) = type_path.path.segments.first() {
32-
return segment.ident == "MapNested";
33-
}
34-
}
35-
false
36-
};
37-
3820
let transformed_fields = fields.named.iter().map(|f| {
3921
let field_name = &f.ident;
4022
let field_vis = &f.vis;
@@ -56,45 +38,34 @@ pub fn contract_state(_attr: TokenStream, item: TokenStream) -> TokenStream {
5638
}
5739
});
5840

59-
let init_calls = fields.named.iter().map(|f| {
41+
let init_fields = fields.named.iter().map(|f| {
6042
let field = f.ident.as_ref().unwrap();
43+
let field_ty = &f.ty;
6144
let key = field.to_string();
6245

6346
if is_flat(f) {
6447
quote! {
65-
let mut key = prefix.clone();
66-
key.extend_from_slice(#key.as_bytes());
67-
self.#field = LazyCell::new(key);
68-
}
69-
} else if is_map(f) || is_map_nested(f) {
70-
quote! {
71-
let mut key = prefix.clone();
72-
key.extend_from_slice(#key.as_bytes());
73-
self.#field.__init_lazy_fields(key);
48+
#field: {
49+
let mut key = prefix.clone();
50+
key.extend_from_slice(#key.as_bytes());
51+
LazyCell::with_prefix(key)
52+
}
7453
}
7554
} else {
7655
quote! {
77-
let mut key = prefix.clone();
78-
key.extend_from_slice(#key.as_bytes());
79-
key.push(b':');
80-
self.#field.__init_lazy_fields(key);
56+
#field: {
57+
let mut key = prefix.clone();
58+
key.extend_from_slice(#key.as_bytes());
59+
key.push(b':');
60+
#field_ty::with_prefix(key)
61+
}
8162
}
8263
}
8364
});
8465

8566
let flush_calls = fields.named.iter().map(|f| {
8667
let field = f.ident.as_ref().unwrap();
87-
88-
if is_flat(f) {
89-
quote! { self.#field.flush(); }
90-
} else {
91-
quote! { self.#field.__flush_lazy_fields(); }
92-
}
93-
});
94-
95-
let default_fields = fields.named.iter().map(|f| {
96-
let field_name = &f.ident;
97-
quote! { #field_name: Default::default() }
68+
quote! { self.#field.flush(); }
9869
});
9970

10071
TokenStream::from(quote! {
@@ -103,18 +74,14 @@ pub fn contract_state(_attr: TokenStream, item: TokenStream) -> TokenStream {
10374
#(#transformed_fields),*
10475
}
10576

106-
impl Default for #name {
107-
fn default() -> Self {
108-
Self { #(#default_fields),* }
109-
}
110-
}
111-
11277
impl ContractState for #name {
113-
fn __init_lazy_fields(&mut self, prefix: alloc::vec::Vec<u8>) {
114-
#(#init_calls)*
78+
fn with_prefix(prefix: alloc::vec::Vec<u8>) -> Self {
79+
Self {
80+
#(#init_fields),*
81+
}
11582
}
11683

117-
fn __flush_lazy_fields(&self) {
84+
fn flush(&self) {
11885
#(#flush_calls)*
11986
}
12087
}
@@ -132,6 +99,21 @@ pub fn contract(_attr: TokenStream, item: TokenStream) -> TokenStream {
13299
item
133100
}
134101

102+
fn is_integer_type(ty: &Type) -> bool {
103+
if let Type::Path(type_path) = ty {
104+
if let Some(segment) = type_path.path.segments.first() {
105+
let ident = &segment.ident;
106+
return matches!(
107+
ident.to_string().as_str(),
108+
"i8" | "i16" | "i32" | "i64" | "i128" |
109+
"u8" | "u16" | "u32" | "u64" | "u128" |
110+
"isize" | "usize"
111+
);
112+
}
113+
}
114+
false
115+
}
116+
135117
fn handle_impl_block(impl_block: ItemImpl) -> TokenStream {
136118
let self_ty = &impl_block.self_ty;
137119
let mut methods = Vec::new();
@@ -154,12 +136,22 @@ fn handle_impl_block(impl_block: ItemImpl) -> TokenStream {
154136
.filter_map(|arg| match arg {
155137
FnArg::Typed(pat_type) => {
156138
let param = &pat_type.pat;
139+
let ty = &pat_type.ty;
157140
let ptr = syn::Ident::new(&format!("{}_ptr", quote!(#param)), name.span());
158-
let deser = match &*pat_type.ty {
159-
Type::Path(tp) if quote!(#tp).to_string().contains("String") => quote!(read_string),
160-
_ => quote!(read_bytes),
141+
142+
let deser = if let Type::Path(tp) = &**ty {
143+
if quote!(#tp).to_string().contains("String") {
144+
quote!(read_string(#ptr))
145+
} else if is_integer_type(ty) {
146+
quote!(#ty::from_bytes(read_bytes(#ptr)))
147+
} else {
148+
quote!(read_bytes(#ptr))
149+
}
150+
} else {
151+
quote!(read_bytes(#ptr))
161152
};
162-
Some((quote!(#ptr: i32), quote!(let #param = #deser(#ptr);), quote!(#param)))
153+
154+
Some((quote!(#ptr: i32), quote!(let #param = #deser;), quote!(#param)))
163155
}
164156
_ => None,
165157
})
@@ -184,19 +176,17 @@ fn handle_impl_block(impl_block: ItemImpl) -> TokenStream {
184176
let body = if has_return {
185177
quote! {
186178
#(#deserializations)*
187-
let mut state = #self_ty::default();
188-
state.__init_lazy_fields(alloc::vec::Vec::new());
179+
let mut state = <#self_ty as ContractState>::with_prefix(alloc::vec::Vec::new());
189180
let result = state.#call;
190-
state.__flush_lazy_fields();
181+
state.flush();
191182
ret(result);
192183
}
193184
} else {
194185
quote! {
195186
#(#deserializations)*
196-
let mut state = #self_ty::default();
197-
state.__init_lazy_fields(alloc::vec::Vec::new());
187+
let mut state = <#self_ty as ContractState>::with_prefix(alloc::vec::Vec::new());
198188
state.#call;
199-
state.__flush_lazy_fields();
189+
state.flush();
200190
}
201191
};
202192

@@ -228,10 +218,19 @@ fn handle_function(input: ItemFn) -> TokenStream {
228218
for arg in inputs.iter() {
229219
if let FnArg::Typed(pat_type) = arg {
230220
let param = &pat_type.pat;
221+
let ty = &pat_type.ty;
231222
let ptr = syn::Ident::new(&format!("arg{}_ptr", idx), name.span());
232-
let deser = match &*pat_type.ty {
233-
Type::Path(tp) if quote!(#tp).to_string().contains("String") => quote!(read_string),
234-
_ => quote!(read_bytes),
223+
224+
let deser = if let Type::Path(tp) = &**ty {
225+
if quote!(#tp).to_string().contains("String") {
226+
quote!(read_string(#ptr))
227+
} else if is_integer_type(ty) {
228+
quote!(#ty::from_bytes(read_bytes(#ptr)))
229+
} else {
230+
quote!(read_bytes(#ptr))
231+
}
232+
} else {
233+
quote!(read_bytes(#ptr))
235234
};
236235

237236
if idx > 0 {
@@ -242,7 +241,7 @@ fn handle_function(input: ItemFn) -> TokenStream {
242241
call_args.extend(quote!(#param));
243242
}
244243

245-
deserializations.extend(quote! { let #param = #deser(#ptr); });
244+
deserializations.extend(quote! { let #param = #deser; });
246245
idx += 1;
247246
}
248247
}

0 commit comments

Comments
 (0)