nargo/foreign_calls/
layers.rs1use acvm::{AcirField, acir::brillig::ForeignCallResult, pwg::ForeignCallWaitInfo};
2
3use super::{ForeignCallError, ForeignCallExecutor};
4
5pub struct Empty;
15
16impl<F: AcirField> ForeignCallExecutor<F> for Empty {
17 fn execute(
18 &mut self,
19 _foreign_call: &ForeignCallWaitInfo<F>,
20 ) -> Result<ForeignCallResult<F>, ForeignCallError> {
21 Ok(ForeignCallResult::default())
22 }
23}
24
25pub struct Unhandled;
27
28impl<F: AcirField> ForeignCallExecutor<F> for Unhandled {
29 fn execute(
30 &mut self,
31 foreign_call: &ForeignCallWaitInfo<F>,
32 ) -> Result<ForeignCallResult<F>, ForeignCallError> {
33 Err(ForeignCallError::NoHandler(foreign_call.function.clone()))
34 }
35}
36
37pub struct Layer<H, I> {
39 pub handler: H,
40 pub inner: I,
41}
42
43impl<H, I, F> ForeignCallExecutor<F> for Layer<H, I>
44where
45 H: ForeignCallExecutor<F>,
46 I: ForeignCallExecutor<F>,
47{
48 fn execute(
49 &mut self,
50 foreign_call: &ForeignCallWaitInfo<F>,
51 ) -> Result<ForeignCallResult<F>, ForeignCallError> {
52 match self.handler.execute(foreign_call) {
53 Err(ForeignCallError::NoHandler(_)) => self.inner.execute(foreign_call),
54 handled => handled,
55 }
56 }
57}
58
59impl<H, I> Layer<H, I> {
60 pub fn new(handler: H, inner: I) -> Self {
62 Self { handler, inner }
63 }
64}
65
66impl<H> Layer<H, Empty> {
67 pub fn or_empty(handler: H) -> Self {
70 Self { handler, inner: Empty }
71 }
72}
73
74impl<H> Layer<H, Unhandled> {
75 pub fn or_unhandled(handler: H) -> Self {
78 Self { handler, inner: Unhandled }
79 }
80}
81
82impl Layer<Unhandled, Unhandled> {
83 pub fn unhandled() -> Self {
85 Self { handler: Unhandled, inner: Unhandled }
86 }
87}
88
89impl<H, I> Layer<H, I> {
90 pub fn add_layer<J>(self, handler: J) -> Layer<J, Self> {
92 Layer::new(handler, self)
93 }
94
95 pub fn handler(&self) -> &H {
96 &self.handler
97 }
98
99 pub fn inner(&self) -> &I {
100 &self.inner
101 }
102}
103
104pub trait Layering {
106 fn add_layer<L, F>(self, other: L) -> Layer<L, Self>
109 where
110 Self: Sized + ForeignCallExecutor<F>,
111 L: ForeignCallExecutor<F>;
112}
113
114impl<T> Layering for T {
115 fn add_layer<L, F>(self, other: L) -> Layer<L, T>
116 where
117 T: Sized + ForeignCallExecutor<F>,
118 L: ForeignCallExecutor<F>,
119 {
120 Layer::new(other, self)
121 }
122}
123
124pub enum Either<L, R> {
126 Left(L),
127 Right(R),
128}
129
130impl<L, R, F> ForeignCallExecutor<F> for Either<L, R>
131where
132 L: ForeignCallExecutor<F>,
133 R: ForeignCallExecutor<F>,
134{
135 fn execute(
136 &mut self,
137 foreign_call: &ForeignCallWaitInfo<F>,
138 ) -> Result<ForeignCallResult<F>, ForeignCallError> {
139 match self {
140 Either::Left(left) => left.execute(foreign_call),
141 Either::Right(right) => right.execute(foreign_call),
142 }
143 }
144}
145
146impl<H, F> ForeignCallExecutor<F> for Option<H>
150where
151 H: ForeignCallExecutor<F>,
152{
153 fn execute(
154 &mut self,
155 foreign_call: &ForeignCallWaitInfo<F>,
156 ) -> Result<ForeignCallResult<F>, ForeignCallError> {
157 match self {
158 Some(handler) => handler.execute(foreign_call),
159 None => Err(ForeignCallError::NoHandler(foreign_call.function.clone())),
160 }
161 }
162}