multiversx_sc/types/interaction/tx_result_handler_list/
tx_result_handler_list_exec.rs

1use crate::types::{OriginalResultMarker, TxEnv};
2
3use super::{ConsNoRet, ConsRet, RHList, RHListItem};
4
5/// Indicates how result processing will undergo for one specific result handler.
6///
7/// Note that the `ResultType` needs to be the first generic type in the definition,
8/// so we can add new implementations of the same result handlers for new raw result types in subsequent crates.
9pub trait RHListItemExec<RawResult, Env, Original>: RHListItem<Env, Original>
10where
11    Env: TxEnv,
12{
13    /// Part of the execution pre-processing, each result handler needs to produce an "expect" field,
14    /// as defined in the environment.
15    ///
16    /// The operation is chained, so all result handlers can contribute, hence the `prev` argument,
17    /// which represents the "expect" field produces by the other result handlers.
18    ///
19    /// The default behavior is to leave it unchanged.
20    fn item_preprocessing(&self, prev: Env::RHExpect) -> Env::RHExpect {
21        prev
22    }
23
24    /// The main functionality of a result handler, it either does some computation internally
25    /// (e.g. execution of a lambda function), or produces a result, or both.
26    fn item_process_result(self, raw_result: &RawResult) -> Self::Returns;
27}
28
29/// Indicates how result processing will undergo for an ensemble of result handlers.
30pub trait RHListExec<RawResult, Env>: RHList<Env>
31where
32    Env: TxEnv,
33{
34    /// Provides the execution pre-processing, in which result handlers collectively produce an "expect" field.
35    ///
36    /// The operation starts with the default "expect" field, which normally has all fields unspecified, except
37    /// for the "status", which is by default set to "0". This means that failing transactions will cause a panic
38    /// unless explicitly stated in one of the result handlers.
39    fn list_preprocessing(&self) -> Env::RHExpect;
40
41    /// Aggregates the executions of all result handlers, as configured for a transaction.
42    fn list_process_result(self, raw_result: &RawResult) -> Self::ListReturns;
43}
44
45impl<RawResult, Env> RHListExec<RawResult, Env> for ()
46where
47    Env: TxEnv,
48{
49    fn list_preprocessing(&self) -> Env::RHExpect {
50        Env::RHExpect::default()
51    }
52
53    fn list_process_result(self, _raw_result: &RawResult) -> Self::ListReturns {}
54}
55
56impl<RawResult, Env, O> RHListExec<RawResult, Env> for OriginalResultMarker<O>
57where
58    Env: TxEnv,
59{
60    fn list_preprocessing(&self) -> Env::RHExpect {
61        Env::RHExpect::default()
62    }
63
64    fn list_process_result(self, _raw_result: &RawResult) -> Self::ListReturns {}
65}
66
67impl<RawResult, Env, Head, Tail> RHListExec<RawResult, Env> for ConsRet<Env, Head, Tail>
68where
69    Env: TxEnv,
70    Head: RHListItemExec<RawResult, Env, Tail::OriginalResult>,
71    Tail: RHListExec<RawResult, Env>,
72{
73    fn list_preprocessing(&self) -> Env::RHExpect {
74        self.head.item_preprocessing(self.tail.list_preprocessing())
75    }
76
77    fn list_process_result(self, raw_result: &RawResult) -> Self::ListReturns {
78        let head_result = self.head.item_process_result(raw_result);
79        let tail_result = self.tail.list_process_result(raw_result);
80        (head_result, tail_result)
81    }
82}
83
84impl<RawResult, Env, Head, Tail> RHListExec<RawResult, Env> for ConsNoRet<Env, Head, Tail>
85where
86    Env: TxEnv,
87    Head: RHListItemExec<RawResult, Env, Tail::OriginalResult, Returns = ()>,
88    Tail: RHListExec<RawResult, Env>,
89{
90    fn list_preprocessing(&self) -> Env::RHExpect {
91        self.head.item_preprocessing(self.tail.list_preprocessing())
92    }
93
94    fn list_process_result(self, raw_result: &RawResult) -> Self::ListReturns {
95        self.head.item_process_result(raw_result);
96        self.tail.list_process_result(raw_result)
97    }
98}