app_bridge 1.0.0 → 2.0.1
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/.tool-versions +1 -0
- data/Cargo.lock +354 -204
- data/Cargo.toml +1 -1
- data/ext/app_bridge/src/error_mapping.rs +30 -0
- data/ext/app_bridge/src/lib.rs +22 -266
- data/ext/app_bridge/src/wrappers/account.rs +60 -0
- data/ext/app_bridge/src/wrappers/app.rs +114 -0
- data/ext/app_bridge/src/wrappers/mod.rs +5 -0
- data/ext/app_bridge/src/wrappers/trigger_context.rs +64 -0
- data/ext/app_bridge/src/wrappers/trigger_event.rs +63 -0
- data/ext/app_bridge/src/wrappers/trigger_response.rs +42 -0
- data/ext/app_bridge/wit/world.wit +48 -10
- data/lib/app_bridge/version.rb +1 -1
- data/tasks/fixtures.rake +15 -8
- metadata +11 -6
data/Cargo.toml
CHANGED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
use crate::component::standout::app::types::{AppError, ErrorCode};
|
|
2
|
+
use magnus::{self, Error, Ruby, ExceptionClass};
|
|
3
|
+
|
|
4
|
+
impl From<ErrorCode> for ExceptionClass {
|
|
5
|
+
fn from(value: ErrorCode) -> Self {
|
|
6
|
+
fn get_class(name: &str) -> ExceptionClass {
|
|
7
|
+
let ruby = Ruby::get().unwrap();
|
|
8
|
+
ruby.eval::<ExceptionClass>(name).unwrap()
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
match value {
|
|
12
|
+
ErrorCode::Unauthenticated => get_class("AppBridge::UnauthenticatedError"),
|
|
13
|
+
ErrorCode::Forbidden => get_class("AppBridge::ForbiddenError"),
|
|
14
|
+
ErrorCode::Misconfigured => get_class("AppBridge::MisconfiguredError"),
|
|
15
|
+
ErrorCode::Unsupported => get_class("AppBridge::UnsupportedError"),
|
|
16
|
+
ErrorCode::RateLimit => get_class("AppBridge::RateLimitError"),
|
|
17
|
+
ErrorCode::Timeout => get_class("AppBridge::TimeoutError"),
|
|
18
|
+
ErrorCode::Unavailable => get_class("AppBridge::UnavailableError"),
|
|
19
|
+
ErrorCode::InternalError => get_class("AppBridge::InternalError"),
|
|
20
|
+
ErrorCode::MalformedResponse => get_class("AppBridge::MalformedResponseError"),
|
|
21
|
+
ErrorCode::Other => get_class("AppBridge::OtherError"),
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
impl From<AppError> for Error {
|
|
27
|
+
fn from(value: AppError) -> Self {
|
|
28
|
+
Error::new(value.code.into(), value.message)
|
|
29
|
+
}
|
|
30
|
+
}
|
data/ext/app_bridge/src/lib.rs
CHANGED
|
@@ -1,274 +1,32 @@
|
|
|
1
|
-
use magnus::{function, method, prelude::*, Error,
|
|
2
|
-
use std::cell::RefCell;
|
|
3
|
-
use wasmtime::Store;
|
|
1
|
+
use magnus::{function, method, prelude::*, Error, Ruby};
|
|
4
2
|
mod app_state;
|
|
5
3
|
mod component;
|
|
6
4
|
mod request_builder;
|
|
5
|
+
mod error_mapping;
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
use
|
|
10
|
-
use
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
component_path: String,
|
|
15
|
-
instance: RefCell<Option<Bridge>>,
|
|
16
|
-
store: RefCell<Option<Store<AppState>>>,
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
#[derive(Default)]
|
|
20
|
-
#[magnus::wrap(class = "AppBridge::App")]
|
|
21
|
-
struct MutRApp(RefCell<RApp>);
|
|
22
|
-
|
|
23
|
-
impl MutRApp {
|
|
24
|
-
fn initialize(&self, component_path: String) {
|
|
25
|
-
let mut this = self.0.borrow_mut();
|
|
26
|
-
let engine = build_engine();
|
|
27
|
-
let linker = build_linker(&engine).unwrap();
|
|
28
|
-
let mut store = build_store(&engine);
|
|
29
|
-
|
|
30
|
-
let app = app(component_path.clone(), engine, &mut store, linker).unwrap();
|
|
31
|
-
|
|
32
|
-
this.component_path = component_path.to_string();
|
|
33
|
-
*this.instance.borrow_mut() = Some(app);
|
|
34
|
-
*this.store.borrow_mut() = Some(store);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
fn triggers(&self) -> Vec<String> {
|
|
38
|
-
let binding = self.0.borrow();
|
|
39
|
-
|
|
40
|
-
let mut instance = binding.instance.borrow_mut();
|
|
41
|
-
let mut store = binding.store.borrow_mut();
|
|
42
|
-
|
|
43
|
-
if let (Some(instance), Some(store)) = (&mut *instance, &mut *store) {
|
|
44
|
-
instance
|
|
45
|
-
.standout_app_triggers()
|
|
46
|
-
.call_get_triggers(store)
|
|
47
|
-
.unwrap()
|
|
48
|
-
} else {
|
|
49
|
-
vec![]
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
fn rb_fetch_events(&self, context: Value) -> RTriggerResponse {
|
|
54
|
-
let context: RTriggerContext = TryConvert::try_convert(context).unwrap();
|
|
55
|
-
let response = self.fetch_events(context.inner);
|
|
56
|
-
|
|
57
|
-
RTriggerResponse::from_trigger_response(response)
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
fn fetch_events(&self, context: TriggerContext) -> TriggerResponse {
|
|
61
|
-
let binding = self.0.borrow();
|
|
62
|
-
|
|
63
|
-
let mut instance = binding.instance.borrow_mut();
|
|
64
|
-
let mut store = binding.store.borrow_mut();
|
|
65
|
-
|
|
66
|
-
if let (Some(instance), Some(store)) = (&mut *instance, &mut *store) {
|
|
67
|
-
instance
|
|
68
|
-
.standout_app_triggers()
|
|
69
|
-
.call_fetch_events(store, &context)
|
|
70
|
-
.unwrap()
|
|
71
|
-
} else {
|
|
72
|
-
TriggerResponse {
|
|
73
|
-
store: context.store,
|
|
74
|
-
events: vec![],
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
#[magnus::wrap(class = "AppBridge::Account")]
|
|
81
|
-
struct RAccount {
|
|
82
|
-
inner: Account,
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
impl RAccount {
|
|
86
|
-
fn new(id: String, name: String, serialized_data: String) -> Self {
|
|
87
|
-
let inner = Account {
|
|
88
|
-
id: id,
|
|
89
|
-
name: name,
|
|
90
|
-
serialized_data: serialized_data,
|
|
91
|
-
};
|
|
92
|
-
Self { inner }
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
fn id(&self) -> String {
|
|
96
|
-
self.inner.id.clone()
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
fn name(&self) -> String {
|
|
100
|
-
self.inner.name.clone()
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
fn serialized_data(&self) -> String {
|
|
104
|
-
self.inner.serialized_data.clone()
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
impl Clone for RAccount {
|
|
109
|
-
fn clone(&self) -> Self {
|
|
110
|
-
Self {
|
|
111
|
-
inner: self.inner.clone(),
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
impl TryConvert for RAccount {
|
|
117
|
-
fn try_convert(val: Value) -> Result<Self, Error> {
|
|
118
|
-
let id: String = val.funcall("id", ())?;
|
|
119
|
-
let name: String = val.funcall("name", ())?;
|
|
120
|
-
let serialized_data: String = val.funcall("serialized_data", ())?;
|
|
121
|
-
|
|
122
|
-
let inner = Account {
|
|
123
|
-
id,
|
|
124
|
-
name,
|
|
125
|
-
serialized_data,
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
Ok(Self { inner })
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
#[magnus::wrap(class = "AppBridge::TriggerContext")]
|
|
133
|
-
struct RTriggerContext {
|
|
134
|
-
inner: TriggerContext,
|
|
135
|
-
wrapped_account: RAccount,
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
impl RTriggerContext {
|
|
139
|
-
fn new(trigger_id: String, account: Value, store: String) -> Self {
|
|
140
|
-
let account: RAccount = TryConvert::try_convert(account).unwrap();
|
|
141
|
-
|
|
142
|
-
let inner = TriggerContext {
|
|
143
|
-
trigger_id: trigger_id,
|
|
144
|
-
account: account.clone().inner,
|
|
145
|
-
store: store,
|
|
146
|
-
};
|
|
147
|
-
Self {
|
|
148
|
-
inner,
|
|
149
|
-
wrapped_account: account.clone(),
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
fn trigger_id(&self) -> String {
|
|
154
|
-
self.inner.trigger_id.clone()
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
fn account(&self) -> RAccount {
|
|
158
|
-
self.wrapped_account.clone()
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
fn store(&self) -> String {
|
|
162
|
-
self.inner.store.clone()
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
impl TryConvert for RTriggerContext {
|
|
167
|
-
fn try_convert(val: Value) -> Result<Self, Error> {
|
|
168
|
-
let account_val: Value = val.funcall("account", ())?;
|
|
169
|
-
let store: String = val.funcall("store", ())?;
|
|
170
|
-
let trigger_id: String = val.funcall("trigger_id", ())?;
|
|
171
|
-
|
|
172
|
-
let account: RAccount = TryConvert::try_convert(account_val).unwrap();
|
|
173
|
-
|
|
174
|
-
let inner = TriggerContext {
|
|
175
|
-
trigger_id: trigger_id,
|
|
176
|
-
account: account.clone().inner,
|
|
177
|
-
store: store,
|
|
178
|
-
};
|
|
179
|
-
|
|
180
|
-
Ok(Self {
|
|
181
|
-
inner,
|
|
182
|
-
wrapped_account: account.clone(),
|
|
183
|
-
})
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
#[magnus::wrap(class = "AppBridge::TriggerResponse")]
|
|
188
|
-
struct RTriggerResponse {
|
|
189
|
-
inner: TriggerResponse,
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
impl RTriggerResponse {
|
|
193
|
-
fn new(store: String, events: RArray) -> Self {
|
|
194
|
-
let iter = events.into_iter();
|
|
195
|
-
let res: Vec<RTriggerEvent> = iter
|
|
196
|
-
.map(&TryConvert::try_convert)
|
|
197
|
-
.collect::<Result<Vec<RTriggerEvent>, Error>>()
|
|
198
|
-
.unwrap();
|
|
199
|
-
|
|
200
|
-
let inner = TriggerResponse {
|
|
201
|
-
store: store,
|
|
202
|
-
events: res.iter().map(|e| e.inner.clone()).collect(),
|
|
203
|
-
};
|
|
204
|
-
Self { inner }
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
fn from_trigger_response(inner: TriggerResponse) -> Self {
|
|
208
|
-
Self { inner }
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
fn store(&self) -> String {
|
|
212
|
-
self.inner.store.clone()
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
fn events(&self) -> RArray {
|
|
216
|
-
self.inner
|
|
217
|
-
.events
|
|
218
|
-
.iter()
|
|
219
|
-
.map(|e| RTriggerEvent::new(e.id.clone(), e.timestamp, e.serialized_data.clone()))
|
|
220
|
-
.collect()
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
#[magnus::wrap(class = "AppBridge::TriggerEvent")]
|
|
225
|
-
struct RTriggerEvent {
|
|
226
|
-
inner: TriggerEvent,
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
impl RTriggerEvent {
|
|
230
|
-
fn new(id: String, timestamp: u64, serialized_data: String) -> Self {
|
|
231
|
-
let inner = TriggerEvent {
|
|
232
|
-
id: id,
|
|
233
|
-
timestamp: timestamp,
|
|
234
|
-
serialized_data: serialized_data,
|
|
235
|
-
};
|
|
236
|
-
Self { inner }
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
fn id(&self) -> String {
|
|
240
|
-
self.inner.id.clone()
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
fn timestamp(&self) -> u64 {
|
|
244
|
-
self.inner.timestamp
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
fn serialized_data(&self) -> String {
|
|
248
|
-
self.inner.serialized_data.clone()
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
impl TryConvert for RTriggerEvent {
|
|
253
|
-
fn try_convert(val: Value) -> Result<Self, Error> {
|
|
254
|
-
let id: String = val.funcall("id", ())?;
|
|
255
|
-
let timestamp: u64 = val.funcall("timestamp", ())?;
|
|
256
|
-
let serialized_data: String = val.funcall("serialized_data", ())?;
|
|
257
|
-
|
|
258
|
-
let inner = TriggerEvent {
|
|
259
|
-
id,
|
|
260
|
-
timestamp,
|
|
261
|
-
serialized_data,
|
|
262
|
-
};
|
|
263
|
-
|
|
264
|
-
Ok(Self { inner })
|
|
265
|
-
}
|
|
266
|
-
}
|
|
7
|
+
mod wrappers;
|
|
8
|
+
use wrappers::account::RAccount;
|
|
9
|
+
use wrappers::trigger_context::RTriggerContext;
|
|
10
|
+
use wrappers::trigger_event::RTriggerEvent;
|
|
11
|
+
use wrappers::trigger_response::RTriggerResponse;
|
|
12
|
+
use wrappers::app::MutRApp;
|
|
267
13
|
|
|
268
14
|
#[magnus::init]
|
|
269
15
|
fn init(ruby: &Ruby) -> Result<(), Error> {
|
|
270
16
|
let module = ruby.define_module("AppBridge")?;
|
|
271
17
|
|
|
18
|
+
let error = module.define_error("Error", ruby.exception_standard_error())?;
|
|
19
|
+
module.define_error("UnauthenticatedError", error)?;
|
|
20
|
+
module.define_error("ForbiddenError", error)?;
|
|
21
|
+
module.define_error("MisconfiguredError", error)?;
|
|
22
|
+
module.define_error("UnsupportedError", error)?;
|
|
23
|
+
module.define_error("RateLimitError", error)?;
|
|
24
|
+
module.define_error("TimeoutError", error)?;
|
|
25
|
+
module.define_error("UnavailableError", error)?;
|
|
26
|
+
module.define_error("InternalError", error)?;
|
|
27
|
+
module.define_error("MalformedResponseError", error)?;
|
|
28
|
+
module.define_error("OtherError", error)?;
|
|
29
|
+
|
|
272
30
|
// Define the Accout class
|
|
273
31
|
let account_class = module.define_class("Account", ruby.class_object())?;
|
|
274
32
|
account_class.define_singleton_method("new", function!(RAccount::new, 3))?;
|
|
@@ -277,9 +35,8 @@ fn init(ruby: &Ruby) -> Result<(), Error> {
|
|
|
277
35
|
account_class.define_method("serialized_data", method!(RAccount::serialized_data, 0))?;
|
|
278
36
|
|
|
279
37
|
let trigger_event_class = module.define_class("TriggerEvent", ruby.class_object())?;
|
|
280
|
-
trigger_event_class.define_singleton_method("new", function!(RTriggerEvent::new,
|
|
38
|
+
trigger_event_class.define_singleton_method("new", function!(RTriggerEvent::new, 2))?;
|
|
281
39
|
trigger_event_class.define_method("id", method!(RTriggerEvent::id, 0))?;
|
|
282
|
-
trigger_event_class.define_method("timestamp", method!(RTriggerEvent::timestamp, 0))?;
|
|
283
40
|
trigger_event_class.define_method(
|
|
284
41
|
"serialized_data",
|
|
285
42
|
method!(RTriggerEvent::serialized_data, 0),
|
|
@@ -300,9 +57,8 @@ fn init(ruby: &Ruby) -> Result<(), Error> {
|
|
|
300
57
|
let app_class = module.define_class("App", ruby.class_object())?;
|
|
301
58
|
app_class.define_alloc_func::<MutRApp>();
|
|
302
59
|
app_class.define_method("initialize", method!(MutRApp::initialize, 1))?;
|
|
303
|
-
app_class.define_method("
|
|
60
|
+
app_class.define_method("trigger_ids", method!(MutRApp::trigger_ids, 0))?;
|
|
304
61
|
app_class.define_private_method("_rust_fetch_events", method!(MutRApp::rb_fetch_events, 1))?;
|
|
305
62
|
|
|
306
|
-
|
|
307
63
|
Ok(())
|
|
308
64
|
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
use magnus::{prelude::*, Error, TryConvert, Value};
|
|
2
|
+
use crate::component::standout::app::types::Account;
|
|
3
|
+
|
|
4
|
+
#[magnus::wrap(class = "AppBridge::Account")]
|
|
5
|
+
pub struct RAccount {
|
|
6
|
+
pub inner: Account,
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
impl RAccount {
|
|
10
|
+
pub fn new(id: String, name: String, serialized_data: String) -> Self {
|
|
11
|
+
let inner = Account {
|
|
12
|
+
id: id,
|
|
13
|
+
name: name,
|
|
14
|
+
serialized_data: serialized_data,
|
|
15
|
+
};
|
|
16
|
+
Self { inner }
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
pub fn id(&self) -> String {
|
|
20
|
+
self.inner.id.clone()
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
pub fn name(&self) -> String {
|
|
24
|
+
self.inner.name.clone()
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
pub fn serialized_data(&self) -> String {
|
|
28
|
+
self.inner.serialized_data.clone()
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
impl Clone for RAccount {
|
|
33
|
+
fn clone(&self) -> Self {
|
|
34
|
+
Self {
|
|
35
|
+
inner: self.inner.clone(),
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
impl TryConvert for RAccount {
|
|
41
|
+
fn try_convert(val: Value) -> Result<Self, Error> {
|
|
42
|
+
let id: String = val.funcall("id", ())?;
|
|
43
|
+
let name: String = val.funcall("name", ())?;
|
|
44
|
+
let serialized_data: String = val.funcall("serialized_data", ())?;
|
|
45
|
+
|
|
46
|
+
let inner = Account {
|
|
47
|
+
id,
|
|
48
|
+
name,
|
|
49
|
+
serialized_data,
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
Ok(Self { inner })
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
impl From<RAccount> for Account {
|
|
57
|
+
fn from(raccount: RAccount) -> Self {
|
|
58
|
+
raccount.inner
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
use magnus::{Error, TryConvert, Value};
|
|
2
|
+
use std::cell::RefCell;
|
|
3
|
+
use wasmtime::Store;
|
|
4
|
+
|
|
5
|
+
use crate::app_state::AppState;
|
|
6
|
+
use crate::component::standout::app::types::{TriggerContext, TriggerResponse, AppError, ErrorCode};
|
|
7
|
+
use crate::component::{app, build_engine, build_linker, build_store, Bridge};
|
|
8
|
+
use super::trigger_context::RTriggerContext;
|
|
9
|
+
|
|
10
|
+
use super::trigger_response::RTriggerResponse;
|
|
11
|
+
|
|
12
|
+
#[derive(Default)]
|
|
13
|
+
pub struct RApp {
|
|
14
|
+
component_path: String,
|
|
15
|
+
instance: RefCell<Option<Bridge>>,
|
|
16
|
+
store: RefCell<Option<Store<AppState>>>,
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
#[derive(Default)]
|
|
20
|
+
#[magnus::wrap(class = "AppBridge::App")]
|
|
21
|
+
pub struct MutRApp(RefCell<RApp>);
|
|
22
|
+
|
|
23
|
+
impl MutRApp {
|
|
24
|
+
pub fn initialize(&self, component_path: String) {
|
|
25
|
+
let mut this = self.0.borrow_mut();
|
|
26
|
+
let engine = build_engine();
|
|
27
|
+
let linker = build_linker(&engine).unwrap();
|
|
28
|
+
let mut store = build_store(&engine);
|
|
29
|
+
|
|
30
|
+
let app = app(component_path.clone(), engine, &mut store, linker).unwrap();
|
|
31
|
+
|
|
32
|
+
this.component_path = component_path.to_string();
|
|
33
|
+
*this.instance.borrow_mut() = Some(app);
|
|
34
|
+
*this.store.borrow_mut() = Some(store);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
pub fn trigger_ids(&self) -> Result<Vec<String>, Error> {
|
|
38
|
+
let binding = self.0.borrow();
|
|
39
|
+
|
|
40
|
+
let mut instance = binding.instance.borrow_mut();
|
|
41
|
+
let mut store = binding.store.borrow_mut();
|
|
42
|
+
|
|
43
|
+
if let (Some(instance), Some(store)) = (&mut *instance, &mut *store) {
|
|
44
|
+
match instance.standout_app_triggers().call_trigger_ids(store) {
|
|
45
|
+
Ok(result) => {
|
|
46
|
+
match result {
|
|
47
|
+
Ok(ids) => Ok(ids),
|
|
48
|
+
Err(err) => Err(err.into())
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
Err(err) => {
|
|
52
|
+
if let Some(wit_err) = err.downcast_ref::<AppError>() {
|
|
53
|
+
Err(wit_err.clone().into())
|
|
54
|
+
} else {
|
|
55
|
+
Err(AppError {
|
|
56
|
+
code: ErrorCode::InternalError,
|
|
57
|
+
message: format!("Unexpected error: {:?}", err),
|
|
58
|
+
}.into())
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
}
|
|
62
|
+
} else {
|
|
63
|
+
Err(AppError {
|
|
64
|
+
code: ErrorCode::InternalError,
|
|
65
|
+
message: "App instance couln't be initialized".to_string(),
|
|
66
|
+
}.into())
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
pub fn rb_fetch_events(&self, context: Value) -> Result<RTriggerResponse, magnus::Error> {
|
|
71
|
+
let context: RTriggerContext = TryConvert::try_convert(context).unwrap();
|
|
72
|
+
let response = self.fetch_events(context.into());
|
|
73
|
+
|
|
74
|
+
match response {
|
|
75
|
+
Ok(response) => Ok(response.into()),
|
|
76
|
+
Err(err) => Err(err.into())
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
fn fetch_events(&self, context: TriggerContext) -> Result<TriggerResponse, AppError> {
|
|
81
|
+
let binding = self.0.borrow();
|
|
82
|
+
|
|
83
|
+
let mut instance = binding.instance.borrow_mut();
|
|
84
|
+
let mut store = binding.store.borrow_mut();
|
|
85
|
+
|
|
86
|
+
if let (Some(instance), Some(store)) = (&mut *instance, &mut *store) {
|
|
87
|
+
match instance
|
|
88
|
+
.standout_app_triggers()
|
|
89
|
+
.call_fetch_events(store, &context) {
|
|
90
|
+
Ok(response) => {
|
|
91
|
+
match response {
|
|
92
|
+
Ok(res) => Ok(res),
|
|
93
|
+
Err(err) => Err(err),
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
Err(err) => {
|
|
97
|
+
if let Some(wit_err) = err.downcast_ref::<AppError>() {
|
|
98
|
+
Err(AppError::from(wit_err.clone()))
|
|
99
|
+
} else {
|
|
100
|
+
Err(AppError {
|
|
101
|
+
code: ErrorCode::InternalError,
|
|
102
|
+
message: format!("Unexpected error: {:?}", err),
|
|
103
|
+
})
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
} else {
|
|
108
|
+
Err(AppError {
|
|
109
|
+
code: ErrorCode::InternalError,
|
|
110
|
+
message: "App instance couln't be initialized".to_string(),
|
|
111
|
+
})
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
use magnus::{prelude::*, Error, TryConvert, Value};
|
|
2
|
+
use crate::component::standout::app::types::TriggerContext;
|
|
3
|
+
use super::account::RAccount;
|
|
4
|
+
|
|
5
|
+
#[magnus::wrap(class = "AppBridge::TriggerContext")]
|
|
6
|
+
pub struct RTriggerContext {
|
|
7
|
+
inner: TriggerContext,
|
|
8
|
+
wrapped_account: RAccount,
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
impl RTriggerContext {
|
|
12
|
+
pub fn new(trigger_id: String, account: Value, store: String) -> Self {
|
|
13
|
+
let account: RAccount = TryConvert::try_convert(account).unwrap();
|
|
14
|
+
|
|
15
|
+
let inner = TriggerContext {
|
|
16
|
+
trigger_id: trigger_id,
|
|
17
|
+
account: account.clone().into(),
|
|
18
|
+
store: store,
|
|
19
|
+
};
|
|
20
|
+
Self {
|
|
21
|
+
inner,
|
|
22
|
+
wrapped_account: account.clone(),
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
pub fn trigger_id(&self) -> String {
|
|
27
|
+
self.inner.trigger_id.clone()
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
pub fn account(&self) -> RAccount {
|
|
31
|
+
self.wrapped_account.clone()
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
pub fn store(&self) -> String {
|
|
35
|
+
self.inner.store.clone()
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
impl TryConvert for RTriggerContext {
|
|
40
|
+
fn try_convert(val: Value) -> Result<Self, Error> {
|
|
41
|
+
let account_val: Value = val.funcall("account", ())?;
|
|
42
|
+
let store: String = val.funcall("store", ())?;
|
|
43
|
+
let trigger_id: String = val.funcall("trigger_id", ())?;
|
|
44
|
+
|
|
45
|
+
let account: RAccount = TryConvert::try_convert(account_val).unwrap();
|
|
46
|
+
|
|
47
|
+
let inner = TriggerContext {
|
|
48
|
+
trigger_id: trigger_id,
|
|
49
|
+
account: account.clone().inner,
|
|
50
|
+
store: store,
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
Ok(Self {
|
|
54
|
+
inner,
|
|
55
|
+
wrapped_account: account.clone(),
|
|
56
|
+
})
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
impl From<RTriggerContext> for TriggerContext {
|
|
61
|
+
fn from(rtrigger_context: RTriggerContext) -> Self {
|
|
62
|
+
rtrigger_context.inner
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
use magnus::{prelude::*, Error, TryConvert, Value};
|
|
2
|
+
use crate::component::standout::app::types::TriggerEvent;
|
|
3
|
+
|
|
4
|
+
#[magnus::wrap(class = "AppBridge::TriggerEvent")]
|
|
5
|
+
pub struct RTriggerEvent {
|
|
6
|
+
inner: TriggerEvent,
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
impl RTriggerEvent {
|
|
10
|
+
pub fn new(id: String, serialized_data: String) -> Self {
|
|
11
|
+
let inner: TriggerEvent = TriggerEvent {
|
|
12
|
+
id: id,
|
|
13
|
+
serialized_data: serialized_data,
|
|
14
|
+
};
|
|
15
|
+
Self { inner }
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
pub fn id(&self) -> String {
|
|
19
|
+
self.inner.id.clone()
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
pub fn serialized_data(&self) -> String {
|
|
23
|
+
self.inner.serialized_data.clone()
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
impl TryConvert for RTriggerEvent {
|
|
28
|
+
fn try_convert(val: Value) -> Result<Self, Error> {
|
|
29
|
+
let id: String = val.funcall("id", ())?;
|
|
30
|
+
let serialized_data: String = val.funcall("serialized_data", ())?;
|
|
31
|
+
|
|
32
|
+
let inner = TriggerEvent {
|
|
33
|
+
id,
|
|
34
|
+
serialized_data,
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
Ok(Self { inner })
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
impl From<RTriggerEvent> for TriggerEvent {
|
|
42
|
+
fn from(rtrigger_event: RTriggerEvent) -> Self {
|
|
43
|
+
rtrigger_event.inner
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
impl From<TriggerEvent> for RTriggerEvent {
|
|
48
|
+
fn from(trigger_event: TriggerEvent) -> Self {
|
|
49
|
+
Self { inner: trigger_event }
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
impl From<&RTriggerEvent> for TriggerEvent {
|
|
54
|
+
fn from(rtrigger_event: &RTriggerEvent) -> Self {
|
|
55
|
+
rtrigger_event.inner.clone()
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
impl From<&TriggerEvent> for RTriggerEvent {
|
|
60
|
+
fn from(trigger_event: &TriggerEvent) -> Self {
|
|
61
|
+
Self { inner: trigger_event.clone() }
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
use magnus::{Error, RArray, TryConvert};
|
|
2
|
+
use crate::component::standout::app::types::TriggerResponse;
|
|
3
|
+
use super::trigger_event::RTriggerEvent;
|
|
4
|
+
|
|
5
|
+
#[magnus::wrap(class = "AppBridge::TriggerResponse")]
|
|
6
|
+
pub struct RTriggerResponse {
|
|
7
|
+
inner: TriggerResponse,
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
impl RTriggerResponse {
|
|
11
|
+
pub fn new(store: String, events: RArray) -> Self {
|
|
12
|
+
let iter = events.into_iter();
|
|
13
|
+
let res: Vec<RTriggerEvent> = iter
|
|
14
|
+
.map(&TryConvert::try_convert)
|
|
15
|
+
.collect::<Result<Vec<RTriggerEvent>, Error>>()
|
|
16
|
+
.unwrap();
|
|
17
|
+
|
|
18
|
+
let inner = TriggerResponse {
|
|
19
|
+
store: store,
|
|
20
|
+
events: res.iter().map(|e| e.into()).collect(),
|
|
21
|
+
};
|
|
22
|
+
Self { inner }
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
pub fn store(&self) -> String {
|
|
26
|
+
self.inner.store.clone()
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
pub fn events(&self) -> RArray {
|
|
30
|
+
self.inner
|
|
31
|
+
.events
|
|
32
|
+
.iter()
|
|
33
|
+
.map(|e| RTriggerEvent::from(e))
|
|
34
|
+
.collect()
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
impl From<TriggerResponse> for RTriggerResponse {
|
|
39
|
+
fn from(value: TriggerResponse) -> Self {
|
|
40
|
+
Self { inner: value }
|
|
41
|
+
}
|
|
42
|
+
}
|