app_bridge 3.0.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -0
- data/.tool-versions +1 -1
- data/Cargo.lock +292 -751
- data/Cargo.toml +1 -1
- data/README.md +213 -2
- data/ext/app_bridge/Cargo.toml +8 -4
- data/ext/app_bridge/src/app_state.rs +29 -13
- data/ext/app_bridge/src/component.rs +256 -46
- data/ext/app_bridge/src/error_mapping.rs +24 -24
- data/ext/app_bridge/src/file_ops.rs +325 -0
- data/ext/app_bridge/src/lib.rs +5 -1
- data/ext/app_bridge/src/request_builder.rs +270 -152
- data/ext/app_bridge/src/types.rs +78 -0
- data/ext/app_bridge/src/wrappers/action_context.rs +3 -3
- data/ext/app_bridge/src/wrappers/action_response.rs +7 -3
- data/ext/app_bridge/src/wrappers/app.rs +112 -148
- data/ext/app_bridge/src/wrappers/connection.rs +4 -4
- data/ext/app_bridge/src/wrappers/trigger_context.rs +7 -7
- data/ext/app_bridge/src/wrappers/trigger_event.rs +4 -4
- data/ext/app_bridge/src/wrappers/trigger_response.rs +29 -28
- data/ext/app_bridge/wit/{world.wit → v3/world.wit} +3 -0
- data/ext/app_bridge/wit/v4/world.wit +328 -0
- data/lib/app_bridge/app.rb +21 -2
- data/lib/app_bridge/file_processor.rb +131 -0
- data/lib/app_bridge/version.rb +1 -1
- data/lib/app_bridge.rb +26 -0
- data/tasks/fixtures.rake +16 -2
- metadata +8 -4
|
@@ -1,178 +1,291 @@
|
|
|
1
1
|
use crate::app_state::AppState;
|
|
2
|
-
use crate::component::
|
|
3
|
-
|
|
4
|
-
};
|
|
2
|
+
use crate::component::{v3, v4};
|
|
3
|
+
use crate::component::v4::standout::app::http::{Method, Request, RequestError, Response};
|
|
5
4
|
use reqwest::Method as ReqwestMethod;
|
|
6
5
|
use std::result::Result::Ok;
|
|
7
6
|
use wasmtime::component::Resource;
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// Macro to implement HostRequestBuilder for any version
|
|
10
|
+
//
|
|
11
|
+
// When adding a new version, just add:
|
|
12
|
+
// impl_host_request_builder!(v5);
|
|
13
|
+
// impl_http_type_conversions!(v5);
|
|
14
|
+
// ============================================================================
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
self.next_request_id += 1;
|
|
27
|
-
self.request_list.insert(new_id, request);
|
|
28
|
-
Resource::new_own(new_id)
|
|
29
|
-
}
|
|
16
|
+
macro_rules! impl_host_request_builder {
|
|
17
|
+
($v:ident) => {
|
|
18
|
+
impl $v::standout::app::http::HostRequestBuilder for AppState {
|
|
19
|
+
fn new(&mut self) -> Resource<$v::standout::app::http::RequestBuilder> {
|
|
20
|
+
let id = self.next_request_id;
|
|
21
|
+
self.next_request_id += 1;
|
|
22
|
+
self.request_list.insert(id, Request::default());
|
|
23
|
+
Resource::new_own(id)
|
|
24
|
+
}
|
|
30
25
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
26
|
+
fn method(
|
|
27
|
+
&mut self,
|
|
28
|
+
self_: Resource<$v::standout::app::http::RequestBuilder>,
|
|
29
|
+
method: $v::standout::app::http::Method,
|
|
30
|
+
) -> Resource<$v::standout::app::http::RequestBuilder> {
|
|
31
|
+
let id = self_.rep();
|
|
32
|
+
if let Some(mut request) = self.request_list.get(&id).cloned() {
|
|
33
|
+
request.method = method.into();
|
|
34
|
+
let new_id = self.next_request_id;
|
|
35
|
+
self.next_request_id += 1;
|
|
36
|
+
self.request_list.insert(new_id, request);
|
|
37
|
+
Resource::new_own(new_id)
|
|
38
|
+
} else {
|
|
39
|
+
Resource::new_own(id)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
44
42
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
43
|
+
fn url(
|
|
44
|
+
&mut self,
|
|
45
|
+
self_: Resource<$v::standout::app::http::RequestBuilder>,
|
|
46
|
+
url: String,
|
|
47
|
+
) -> Resource<$v::standout::app::http::RequestBuilder> {
|
|
48
|
+
let id = self_.rep();
|
|
49
|
+
if let Some(mut request) = self.request_list.get(&id).cloned() {
|
|
50
|
+
request.url = url;
|
|
51
|
+
let new_id = self.next_request_id;
|
|
52
|
+
self.next_request_id += 1;
|
|
53
|
+
self.request_list.insert(new_id, request);
|
|
54
|
+
Resource::new_own(new_id)
|
|
55
|
+
} else {
|
|
56
|
+
Resource::new_own(id)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
fn header(
|
|
61
|
+
&mut self,
|
|
62
|
+
self_: Resource<$v::standout::app::http::RequestBuilder>,
|
|
63
|
+
key: String,
|
|
64
|
+
value: String,
|
|
65
|
+
) -> Resource<$v::standout::app::http::RequestBuilder> {
|
|
66
|
+
let id = self_.rep();
|
|
67
|
+
let mut request = self.request_list.get(&id).cloned().unwrap_or_default();
|
|
68
|
+
request.headers.push((key, value));
|
|
69
|
+
let new_id = self.next_request_id;
|
|
70
|
+
self.next_request_id += 1;
|
|
71
|
+
self.request_list.insert(new_id, request);
|
|
72
|
+
Resource::new_own(new_id)
|
|
73
|
+
}
|
|
60
74
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
75
|
+
fn headers(
|
|
76
|
+
&mut self,
|
|
77
|
+
self_: Resource<$v::standout::app::http::RequestBuilder>,
|
|
78
|
+
headers: Vec<(String, String)>,
|
|
79
|
+
) -> Resource<$v::standout::app::http::RequestBuilder> {
|
|
80
|
+
let id = self_.rep();
|
|
81
|
+
let mut request = self.request_list.get(&id).cloned().unwrap_or_default();
|
|
82
|
+
request.headers.extend(headers);
|
|
83
|
+
let new_id = self.next_request_id;
|
|
84
|
+
self.next_request_id += 1;
|
|
85
|
+
self.request_list.insert(new_id, request);
|
|
86
|
+
Resource::new_own(new_id)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
fn body(
|
|
90
|
+
&mut self,
|
|
91
|
+
self_: Resource<$v::standout::app::http::RequestBuilder>,
|
|
92
|
+
body: String,
|
|
93
|
+
) -> Resource<$v::standout::app::http::RequestBuilder> {
|
|
94
|
+
let id = self_.rep();
|
|
95
|
+
let mut request = self.request_list.get(&id).cloned().unwrap_or_default();
|
|
96
|
+
request.body = body;
|
|
97
|
+
let new_id = self.next_request_id;
|
|
98
|
+
self.next_request_id += 1;
|
|
99
|
+
self.request_list.insert(new_id, request);
|
|
100
|
+
Resource::new_own(new_id)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
fn send(
|
|
104
|
+
&mut self,
|
|
105
|
+
self_: Resource<$v::standout::app::http::RequestBuilder>,
|
|
106
|
+
) -> Result<$v::standout::app::http::Response, $v::standout::app::http::RequestError> {
|
|
107
|
+
let id = self_.rep();
|
|
108
|
+
match self.request_list.get(&id).cloned() {
|
|
109
|
+
Some(request) => send_request(&self.client, &request)
|
|
110
|
+
.map(Into::into)
|
|
111
|
+
.map_err(Into::into),
|
|
112
|
+
None => Err($v::standout::app::http::RequestError::Other(
|
|
113
|
+
"Request not found".to_string(),
|
|
114
|
+
)),
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
fn drop(
|
|
119
|
+
&mut self,
|
|
120
|
+
rep: Resource<$v::standout::app::http::RequestBuilder>,
|
|
121
|
+
) -> wasmtime::Result<()> {
|
|
122
|
+
self.request_list.remove(&rep.rep());
|
|
123
|
+
Ok(())
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
fn object(
|
|
127
|
+
&mut self,
|
|
128
|
+
self_: Resource<$v::standout::app::http::RequestBuilder>,
|
|
129
|
+
) -> $v::standout::app::http::Request {
|
|
130
|
+
self.request_list
|
|
131
|
+
.get(&self_.rep())
|
|
132
|
+
.cloned()
|
|
133
|
+
.unwrap_or_default()
|
|
134
|
+
.into()
|
|
135
|
+
}
|
|
73
136
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
self.request_list.insert(new_id, request);
|
|
77
|
-
Resource::new_own(new_id)
|
|
78
|
-
}
|
|
137
|
+
};
|
|
138
|
+
}
|
|
79
139
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
self_: Resource<RequestBuilder>,
|
|
84
|
-
body: wasmtime::component::__internal::String,
|
|
85
|
-
) -> Resource<RequestBuilder> {
|
|
86
|
-
let id = self_.rep();
|
|
87
|
-
let mut request = self.request_list.get(&id).cloned().unwrap_or_default();
|
|
88
|
-
request.body = body;
|
|
89
|
-
let new_id = self.next_request_id;
|
|
90
|
-
self.next_request_id += 1;
|
|
91
|
-
self.request_list.insert(new_id, request);
|
|
92
|
-
Resource::new_own(new_id)
|
|
93
|
-
}
|
|
140
|
+
// ============================================================================
|
|
141
|
+
// Macro to implement HTTP type conversions for a version
|
|
142
|
+
// ============================================================================
|
|
94
143
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
144
|
+
macro_rules! impl_http_type_conversions {
|
|
145
|
+
($v:ident) => {
|
|
146
|
+
impl From<$v::standout::app::http::Method> for Method {
|
|
147
|
+
fn from(m: $v::standout::app::http::Method) -> Self {
|
|
148
|
+
use $v::standout::app::http::Method as V;
|
|
149
|
+
match m {
|
|
150
|
+
V::Get => Self::Get,
|
|
151
|
+
V::Post => Self::Post,
|
|
152
|
+
V::Put => Self::Put,
|
|
153
|
+
V::Delete => Self::Delete,
|
|
154
|
+
V::Patch => Self::Patch,
|
|
155
|
+
V::Options => Self::Options,
|
|
156
|
+
V::Head => Self::Head,
|
|
157
|
+
}
|
|
158
|
+
}
|
|
106
159
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
value.to_str().unwrap_or_default().to_string(),
|
|
119
|
-
));
|
|
160
|
+
|
|
161
|
+
impl From<Method> for $v::standout::app::http::Method {
|
|
162
|
+
fn from(m: Method) -> Self {
|
|
163
|
+
match m {
|
|
164
|
+
Method::Get => Self::Get,
|
|
165
|
+
Method::Post => Self::Post,
|
|
166
|
+
Method::Put => Self::Put,
|
|
167
|
+
Method::Delete => Self::Delete,
|
|
168
|
+
Method::Patch => Self::Patch,
|
|
169
|
+
Method::Options => Self::Options,
|
|
170
|
+
Method::Head => Self::Head,
|
|
120
171
|
}
|
|
121
|
-
response.body = resp.text().unwrap_or_default();
|
|
122
|
-
Ok(response)
|
|
123
172
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
impl From<Response> for $v::standout::app::http::Response {
|
|
176
|
+
fn from(r: Response) -> Self {
|
|
177
|
+
Self {
|
|
178
|
+
status: r.status,
|
|
179
|
+
headers: r.headers,
|
|
180
|
+
body: r.body,
|
|
181
|
+
}
|
|
133
182
|
}
|
|
134
183
|
}
|
|
135
|
-
}
|
|
136
184
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
185
|
+
impl From<Request> for $v::standout::app::http::Request {
|
|
186
|
+
fn from(r: Request) -> Self {
|
|
187
|
+
Self {
|
|
188
|
+
method: r.method.into(),
|
|
189
|
+
url: r.url,
|
|
190
|
+
headers: r.headers,
|
|
191
|
+
body: r.body,
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
impl From<RequestError> for $v::standout::app::http::RequestError {
|
|
197
|
+
fn from(e: RequestError) -> Self {
|
|
198
|
+
match e {
|
|
199
|
+
RequestError::Other(msg) => Self::Other(msg),
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// ============================================================================
|
|
207
|
+
// Generate implementations for all supported versions
|
|
208
|
+
// When adding v5, just add:
|
|
209
|
+
// impl_host_request_builder!(v5);
|
|
210
|
+
// impl_http_type_conversions!(v5);
|
|
211
|
+
// ============================================================================
|
|
212
|
+
|
|
213
|
+
impl_host_request_builder!(v3);
|
|
214
|
+
impl_host_request_builder!(v4);
|
|
215
|
+
|
|
216
|
+
impl_http_type_conversions!(v3);
|
|
217
|
+
// Note: v4 doesn't need conversions since we use v4 types as the canonical internal types
|
|
218
|
+
|
|
219
|
+
// ============================================================================
|
|
220
|
+
// Shared request sending logic
|
|
221
|
+
// ============================================================================
|
|
222
|
+
|
|
223
|
+
fn send_request(
|
|
224
|
+
client: &std::sync::Arc<std::sync::Mutex<reqwest::blocking::Client>>,
|
|
225
|
+
request: &Request,
|
|
226
|
+
) -> Result<Response, RequestError> {
|
|
227
|
+
let client = client.lock().unwrap();
|
|
228
|
+
let mut builder = client.request(request.method.clone().into(), &request.url);
|
|
229
|
+
|
|
230
|
+
for (key, value) in &request.headers {
|
|
231
|
+
builder = builder.header(key, value);
|
|
141
232
|
}
|
|
233
|
+
builder = builder.body(request.body.clone());
|
|
234
|
+
|
|
235
|
+
match builder.send() {
|
|
236
|
+
Ok(resp) => {
|
|
237
|
+
let headers = resp
|
|
238
|
+
.headers()
|
|
239
|
+
.iter()
|
|
240
|
+
.map(|(k, v)| {
|
|
241
|
+
(
|
|
242
|
+
k.as_str().to_string(),
|
|
243
|
+
v.to_str().unwrap_or_default().to_string(),
|
|
244
|
+
)
|
|
245
|
+
})
|
|
246
|
+
.collect();
|
|
142
247
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
248
|
+
Ok(Response {
|
|
249
|
+
status: resp.status().as_u16(),
|
|
250
|
+
headers,
|
|
251
|
+
body: resp.text().unwrap_or_default(),
|
|
252
|
+
})
|
|
253
|
+
}
|
|
254
|
+
Err(error) => Err(RequestError::Other(format!(
|
|
255
|
+
"Request failed to {} {}: {}",
|
|
256
|
+
request.method, request.url, error
|
|
257
|
+
))),
|
|
146
258
|
}
|
|
147
259
|
}
|
|
148
260
|
|
|
261
|
+
// ============================================================================
|
|
262
|
+
// Standard type implementations (used by all versions)
|
|
263
|
+
// ============================================================================
|
|
264
|
+
|
|
149
265
|
impl From<Method> for ReqwestMethod {
|
|
150
266
|
fn from(method: Method) -> Self {
|
|
151
267
|
match method {
|
|
152
|
-
Method::Get =>
|
|
153
|
-
Method::Post =>
|
|
154
|
-
Method::Put =>
|
|
155
|
-
Method::Delete =>
|
|
156
|
-
Method::Patch =>
|
|
157
|
-
Method::Head =>
|
|
158
|
-
Method::Options =>
|
|
268
|
+
Method::Get => Self::GET,
|
|
269
|
+
Method::Post => Self::POST,
|
|
270
|
+
Method::Put => Self::PUT,
|
|
271
|
+
Method::Delete => Self::DELETE,
|
|
272
|
+
Method::Patch => Self::PATCH,
|
|
273
|
+
Method::Head => Self::HEAD,
|
|
274
|
+
Method::Options => Self::OPTIONS,
|
|
159
275
|
}
|
|
160
276
|
}
|
|
161
277
|
}
|
|
162
278
|
|
|
163
279
|
impl Default for Request {
|
|
164
280
|
fn default() -> Self {
|
|
165
|
-
let version = env!("CARGO_PKG_VERSION");
|
|
166
|
-
let user_agent = format!("Standout-AppBridge/{version}");
|
|
167
|
-
let headers = vec![
|
|
168
|
-
("User-Agent".to_string(), user_agent.into()),
|
|
169
|
-
];
|
|
170
|
-
|
|
171
281
|
Self {
|
|
172
|
-
url:
|
|
282
|
+
url: String::new(),
|
|
173
283
|
method: Method::Get,
|
|
174
|
-
body:
|
|
175
|
-
headers
|
|
284
|
+
body: String::new(),
|
|
285
|
+
headers: vec![(
|
|
286
|
+
"User-Agent".to_string(),
|
|
287
|
+
format!("Standout-AppBridge/{}", env!("CARGO_PKG_VERSION")),
|
|
288
|
+
)],
|
|
176
289
|
}
|
|
177
290
|
}
|
|
178
291
|
}
|
|
@@ -182,33 +295,38 @@ impl Default for Response {
|
|
|
182
295
|
Self {
|
|
183
296
|
status: 0,
|
|
184
297
|
headers: Vec::new(),
|
|
185
|
-
body:
|
|
298
|
+
body: String::new(),
|
|
186
299
|
}
|
|
187
300
|
}
|
|
188
301
|
}
|
|
189
302
|
|
|
190
303
|
impl std::fmt::Display for Method {
|
|
191
304
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
192
|
-
match self {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
}
|
|
305
|
+
f.write_str(match self {
|
|
306
|
+
Self::Get => "GET",
|
|
307
|
+
Self::Post => "POST",
|
|
308
|
+
Self::Put => "PUT",
|
|
309
|
+
Self::Delete => "DELETE",
|
|
310
|
+
Self::Patch => "PATCH",
|
|
311
|
+
Self::Head => "HEAD",
|
|
312
|
+
Self::Options => "OPTIONS",
|
|
313
|
+
})
|
|
201
314
|
}
|
|
202
315
|
}
|
|
203
316
|
|
|
317
|
+
// ============================================================================
|
|
318
|
+
// Tests
|
|
319
|
+
// ============================================================================
|
|
204
320
|
|
|
205
321
|
#[cfg(test)]
|
|
206
322
|
mod tests {
|
|
207
323
|
use super::*;
|
|
208
|
-
use httpmock::{
|
|
324
|
+
use httpmock::{Method::GET, MockServer};
|
|
209
325
|
|
|
210
326
|
#[test]
|
|
211
327
|
fn sends_request_with_default_user_agent() {
|
|
328
|
+
use v4::standout::app::http::HostRequestBuilder;
|
|
329
|
+
|
|
212
330
|
let version = env!("CARGO_PKG_VERSION");
|
|
213
331
|
let user_agent = format!("Standout-AppBridge/{version}");
|
|
214
332
|
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
//! Canonical types used internally by the bridge.
|
|
2
|
+
//!
|
|
3
|
+
//! These are version-agnostic and converted to/from versioned WIT types at the boundary.
|
|
4
|
+
|
|
5
|
+
use std::fmt;
|
|
6
|
+
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// Canonical Types - used throughout the codebase, not tied to any version
|
|
9
|
+
// ============================================================================
|
|
10
|
+
|
|
11
|
+
#[derive(Debug, Clone)]
|
|
12
|
+
pub struct AppError {
|
|
13
|
+
pub code: ErrorCode,
|
|
14
|
+
pub message: String,
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
impl fmt::Display for AppError {
|
|
18
|
+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
19
|
+
write!(f, "{:?}: {}", self.code, self.message)
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
impl std::error::Error for AppError {}
|
|
24
|
+
|
|
25
|
+
#[derive(Debug, Clone, Copy)]
|
|
26
|
+
pub enum ErrorCode {
|
|
27
|
+
Unauthenticated,
|
|
28
|
+
Forbidden,
|
|
29
|
+
Misconfigured,
|
|
30
|
+
Unsupported,
|
|
31
|
+
RateLimit,
|
|
32
|
+
Timeout,
|
|
33
|
+
Unavailable,
|
|
34
|
+
InternalError,
|
|
35
|
+
MalformedResponse,
|
|
36
|
+
Other,
|
|
37
|
+
CompleteWorkflow,
|
|
38
|
+
CompleteParent,
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
#[derive(Debug, Clone)]
|
|
42
|
+
pub struct Connection {
|
|
43
|
+
pub id: String,
|
|
44
|
+
pub name: String,
|
|
45
|
+
pub serialized_data: String,
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
#[derive(Debug, Clone)]
|
|
49
|
+
pub struct TriggerContext {
|
|
50
|
+
pub trigger_id: String,
|
|
51
|
+
pub connection: Connection,
|
|
52
|
+
pub store: String,
|
|
53
|
+
pub serialized_input: String,
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
#[derive(Debug, Clone)]
|
|
57
|
+
pub struct ActionContext {
|
|
58
|
+
pub action_id: String,
|
|
59
|
+
pub connection: Connection,
|
|
60
|
+
pub serialized_input: String,
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
#[derive(Debug, Clone)]
|
|
64
|
+
pub struct TriggerEvent {
|
|
65
|
+
pub id: String,
|
|
66
|
+
pub serialized_data: String,
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
#[derive(Debug, Clone)]
|
|
70
|
+
pub struct TriggerResponse {
|
|
71
|
+
pub store: String,
|
|
72
|
+
pub events: Vec<TriggerEvent>,
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
#[derive(Debug, Clone)]
|
|
76
|
+
pub struct ActionResponse {
|
|
77
|
+
pub serialized_output: String,
|
|
78
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
use magnus::{prelude::*, Error, TryConvert, Value};
|
|
2
|
-
use crate::
|
|
2
|
+
use crate::types::ActionContext;
|
|
3
3
|
use super::connection::RConnection;
|
|
4
4
|
|
|
5
5
|
#[magnus::wrap(class = "AppBridge::ActionContext")]
|
|
@@ -20,7 +20,7 @@ impl RActionContext {
|
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
let inner = ActionContext {
|
|
23
|
-
action_id
|
|
23
|
+
action_id,
|
|
24
24
|
connection: wrapped_connection.clone().into(),
|
|
25
25
|
serialized_input,
|
|
26
26
|
};
|
|
@@ -60,7 +60,7 @@ impl TryConvert for RActionContext {
|
|
|
60
60
|
};
|
|
61
61
|
|
|
62
62
|
let inner = ActionContext {
|
|
63
|
-
action_id
|
|
63
|
+
action_id,
|
|
64
64
|
connection: wrapped_connection.clone().inner,
|
|
65
65
|
serialized_input,
|
|
66
66
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
use crate::
|
|
1
|
+
use crate::types::ActionResponse;
|
|
2
2
|
|
|
3
3
|
#[magnus::wrap(class = "AppBridge::ActionResponse")]
|
|
4
4
|
pub struct RActionResponse {
|
|
@@ -8,7 +8,7 @@ pub struct RActionResponse {
|
|
|
8
8
|
impl RActionResponse {
|
|
9
9
|
pub fn new(serialized_output: String) -> Self {
|
|
10
10
|
let inner = ActionResponse {
|
|
11
|
-
serialized_output
|
|
11
|
+
serialized_output,
|
|
12
12
|
};
|
|
13
13
|
Self { inner }
|
|
14
14
|
}
|
|
@@ -16,6 +16,11 @@ impl RActionResponse {
|
|
|
16
16
|
pub fn serialized_output(&self) -> String {
|
|
17
17
|
self.inner.serialized_output.clone()
|
|
18
18
|
}
|
|
19
|
+
|
|
20
|
+
/// Returns a new ActionResponse with the given output
|
|
21
|
+
pub fn with_output(&self, value: String) -> Self {
|
|
22
|
+
Self::new(value)
|
|
23
|
+
}
|
|
19
24
|
}
|
|
20
25
|
|
|
21
26
|
impl From<ActionResponse> for RActionResponse {
|
|
@@ -29,4 +34,3 @@ impl From<RActionResponse> for ActionResponse {
|
|
|
29
34
|
value.inner
|
|
30
35
|
}
|
|
31
36
|
}
|
|
32
|
-
|