numbat_wasm/io/
finish.rs

1use crate::numbat_codec::*;
2use crate::*;
3use core::marker::PhantomData;
4
5struct ApiOutput<A, BigInt, BigUint>
6where
7	BigUint: BigUintApi + 'static,
8	BigInt: BigIntApi<BigUint> + 'static,
9	A: ContractIOApi<BigInt, BigUint> + 'static,
10{
11	api: A,
12	_phantom1: PhantomData<BigInt>,
13	_phantom2: PhantomData<BigUint>,
14}
15
16impl<A, BigInt, BigUint> ApiOutput<A, BigInt, BigUint>
17where
18	BigUint: BigUintApi + 'static,
19	BigInt: BigIntApi<BigUint> + 'static,
20	A: ContractIOApi<BigInt, BigUint> + 'static,
21{
22	#[inline]
23	fn new(api: A) -> Self {
24		ApiOutput {
25			api,
26			_phantom1: PhantomData,
27			_phantom2: PhantomData,
28		}
29	}
30}
31
32impl<A, BigInt, BigUint> TopEncodeOutput for ApiOutput<A, BigInt, BigUint>
33where
34	BigUint: BigUintApi + 'static,
35	BigInt: BigIntApi<BigUint> + 'static,
36	A: ContractIOApi<BigInt, BigUint> + 'static,
37{
38	fn set_slice_u8(self, bytes: &[u8]) {
39		self.api.finish_slice_u8(bytes);
40	}
41
42	fn set_u64(self, value: u64) {
43		self.api.finish_u64(value);
44	}
45
46	fn set_i64(self, value: i64) {
47		self.api.finish_i64(value);
48	}
49
50	#[inline]
51	fn set_unit(self) {
52		// nothing: no result produced
53	}
54
55	#[inline]
56	fn set_big_int_handle_or_bytes<F: FnOnce() -> Vec<u8>>(self, handle: i32, _else_bytes: F) {
57		self.api.finish_big_int_raw(handle);
58	}
59
60	#[inline]
61	fn set_big_uint_handle_or_bytes<F: FnOnce() -> Vec<u8>>(self, handle: i32, _else_bytes: F) {
62		self.api.finish_big_uint_raw(handle);
63	}
64}
65
66pub trait EndpointResult<A, BigInt, BigUint>: Sized
67where
68	BigUint: BigUintApi + 'static,
69	BigInt: BigIntApi<BigUint> + 'static,
70	A: ContractHookApi<BigInt, BigUint> + ContractIOApi<BigInt, BigUint> + 'static,
71{
72	fn finish(&self, api: A);
73}
74
75/// All serializable objects can be used as smart contract function result.
76impl<A, BigInt, BigUint, T> EndpointResult<A, BigInt, BigUint> for T
77where
78	T: TopEncode,
79	BigUint: BigUintApi + 'static,
80	BigInt: BigIntApi<BigUint> + 'static,
81	A: ContractHookApi<BigInt, BigUint> + ContractIOApi<BigInt, BigUint> + 'static,
82{
83	fn finish(&self, api: A) {
84		self.top_encode_or_exit(ApiOutput::new(api.clone()), api, finish_exit);
85	}
86}
87
88#[inline(always)]
89fn finish_exit<A, BigInt, BigUint>(api: A, en_err: EncodeError) -> !
90where
91	BigUint: BigUintApi + 'static,
92	BigInt: BigIntApi<BigUint> + 'static,
93	A: ContractHookApi<BigInt, BigUint> + ContractIOApi<BigInt, BigUint> + 'static,
94{
95	api.signal_error(en_err.message_bytes())
96}