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 }
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
75impl<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}