Skip to main content

rpc/natives/transaction/
mod.rs

1//! Transaction-domain natives. Wraps `server::command::{CreateTransaction,
2//! ListTransactions, GetTransaction, UpdateTransaction, DeleteTransaction}`.
3
4mod logical_common;
5mod parse;
6mod render;
7mod run;
8mod run_logical;
9
10#[cfg(test)]
11mod tests;
12#[cfg(test)]
13mod tests_get_transaction;
14#[cfg(test)]
15mod tests_logical;
16#[cfg(test)]
17mod tests_logical_update;
18#[cfg(test)]
19mod tests_parse;
20
21use scripting::runtime::{alloc_string_ref, read_string_arg};
22use wasmtime::{ArrayRef, Caller, Linker, Rooted, StructRef};
23
24use crate::session::SessionData;
25
26use render::alloc_transaction_chain;
27use run::{
28    run_create_transaction, run_delete_transaction, run_get_transaction,
29    run_get_transaction_detail, run_get_transaction_tag, run_list_transactions,
30    run_set_transaction_tag, run_update_transaction,
31};
32use run_logical::{run_create_transaction_logical, run_update_transaction_logical};
33
34pub const REGISTERED_COMMANDS: &[&str] = &[
35    "create-transaction",
36    "create-transaction-logical",
37    "list-transactions",
38    "get-transaction",
39    "get-transaction-detail",
40    "update-transaction",
41    "update-transaction-logical",
42    "delete-transaction",
43    "set-transaction-tag",
44    "get-transaction-tag",
45];
46
47pub fn register(linker: &mut Linker<SessionData>) -> wasmtime::Result<()> {
48    register_readonly(linker)?;
49    register_mutators(linker)?;
50    Ok(())
51}
52
53pub fn register_readonly(linker: &mut Linker<SessionData>) -> wasmtime::Result<()> {
54    linker.func_wrap_async(
55        "nomi",
56        "transaction_list_transactions",
57        |mut caller: Caller<'_, SessionData>,
58         (account_arg,): (Option<Rooted<ArrayRef>>,)|
59         -> Box<
60            dyn std::future::Future<Output = wasmtime::Result<Option<Rooted<StructRef>>>> + Send,
61        > {
62            Box::new(async move {
63                let user_id = caller.data().ctx().user_id;
64                let account_str = read_string_arg(&mut caller, account_arg)?;
65                let result = run_list_transactions(user_id, account_str).await?;
66                alloc_transaction_chain(&mut caller, result).await
67            })
68        },
69    )?;
70    linker.func_wrap_async(
71        "nomi",
72        "transaction_get_transaction",
73        |mut caller: Caller<'_, SessionData>,
74         (id_arg,): (Option<Rooted<ArrayRef>>,)|
75         -> Box<
76            dyn std::future::Future<Output = wasmtime::Result<Option<Rooted<StructRef>>>> + Send,
77        > {
78            Box::new(async move {
79                let user_id = caller.data().ctx().user_id;
80                let id = read_string_arg(&mut caller, id_arg)?;
81                run_get_transaction(&mut caller, user_id, id).await
82            })
83        },
84    )?;
85    linker.func_wrap_async(
86        "nomi",
87        "transaction_get_transaction_detail",
88        |mut caller: Caller<'_, SessionData>,
89         (id_arg,): (Option<Rooted<ArrayRef>>,)|
90         -> Box<
91            dyn std::future::Future<Output = wasmtime::Result<Option<Rooted<ArrayRef>>>> + Send,
92        > {
93            Box::new(async move {
94                let user_id = caller.data().ctx().user_id;
95                let id = read_string_arg(&mut caller, id_arg)?;
96                let plist = run_get_transaction_detail(user_id, id).await?;
97                Ok(match plist {
98                    Some(s) => Some(alloc_string_ref(&mut caller, s.as_bytes())?),
99                    None => None,
100                })
101            })
102        },
103    )?;
104    linker.func_wrap_async(
105        "nomi",
106        "transaction_get_transaction_tag",
107        |mut caller: Caller<'_, SessionData>,
108         (id_arg, name_arg): (Option<Rooted<ArrayRef>>, Option<Rooted<ArrayRef>>)|
109         -> Box<
110            dyn std::future::Future<Output = wasmtime::Result<Option<Rooted<ArrayRef>>>> + Send,
111        > {
112            Box::new(async move {
113                let user_id = caller.data().ctx().user_id;
114                let id = read_string_arg(&mut caller, id_arg)?;
115                let name = read_string_arg(&mut caller, name_arg)?;
116                let value = run_get_transaction_tag(user_id, id, name).await?;
117                Ok(Some(alloc_string_ref(&mut caller, value.as_bytes())?))
118            })
119        },
120    )?;
121    Ok(())
122}
123
124pub fn register_mutators(linker: &mut Linker<SessionData>) -> wasmtime::Result<()> {
125    linker.func_wrap_async(
126        "nomi",
127        "transaction_delete_transaction",
128        |mut caller: Caller<'_, SessionData>,
129         (id_arg,): (Option<Rooted<ArrayRef>>,)|
130         -> Box<dyn std::future::Future<Output = wasmtime::Result<i32>> + Send> {
131            Box::new(async move {
132                let user_id = caller.data().ctx().user_id;
133                let id = read_string_arg(&mut caller, id_arg)?;
134                run_delete_transaction(user_id, id).await
135            })
136        },
137    )?;
138    linker.func_wrap_async(
139        "nomi",
140        "transaction_create_transaction",
141        |mut caller: Caller<'_, SessionData>,
142         (payload_arg,): (Option<Rooted<ArrayRef>>,)|
143         -> Box<
144            dyn std::future::Future<Output = wasmtime::Result<Option<Rooted<ArrayRef>>>> + Send,
145        > {
146            Box::new(async move {
147                let user_id = caller.data().ctx().user_id;
148                let payload = read_string_arg(&mut caller, payload_arg)?;
149                let id = run_create_transaction(user_id, payload).await?;
150                Ok(Some(alloc_string_ref(&mut caller, id.as_bytes())?))
151            })
152        },
153    )?;
154    linker.func_wrap_async(
155        "nomi",
156        "transaction_create_transaction_logical",
157        |mut caller: Caller<'_, SessionData>,
158         (payload_arg,): (Option<Rooted<ArrayRef>>,)|
159         -> Box<
160            dyn std::future::Future<Output = wasmtime::Result<Option<Rooted<ArrayRef>>>> + Send,
161        > {
162            Box::new(async move {
163                let user_id = caller.data().ctx().user_id;
164                let payload = read_string_arg(&mut caller, payload_arg)?;
165                let id = run_create_transaction_logical(user_id, payload).await?;
166                Ok(Some(alloc_string_ref(&mut caller, id.as_bytes())?))
167            })
168        },
169    )?;
170    linker.func_wrap_async(
171        "nomi",
172        "transaction_update_transaction",
173        |mut caller: Caller<'_, SessionData>,
174         (payload_arg,): (Option<Rooted<ArrayRef>>,)|
175         -> Box<
176            dyn std::future::Future<Output = wasmtime::Result<Option<Rooted<ArrayRef>>>> + Send,
177        > {
178            Box::new(async move {
179                let user_id = caller.data().ctx().user_id;
180                let payload = read_string_arg(&mut caller, payload_arg)?;
181                let id = run_update_transaction(user_id, payload).await?;
182                Ok(Some(alloc_string_ref(&mut caller, id.as_bytes())?))
183            })
184        },
185    )?;
186    linker.func_wrap_async(
187        "nomi",
188        "transaction_update_transaction_logical",
189        |mut caller: Caller<'_, SessionData>,
190         (payload_arg,): (Option<Rooted<ArrayRef>>,)|
191         -> Box<
192            dyn std::future::Future<Output = wasmtime::Result<Option<Rooted<ArrayRef>>>> + Send,
193        > {
194            Box::new(async move {
195                let user_id = caller.data().ctx().user_id;
196                let payload = read_string_arg(&mut caller, payload_arg)?;
197                let id = run_update_transaction_logical(user_id, payload).await?;
198                Ok(Some(alloc_string_ref(&mut caller, id.as_bytes())?))
199            })
200        },
201    )?;
202    linker.func_wrap_async(
203        "nomi",
204        "transaction_set_transaction_tag",
205        |mut caller: Caller<'_, SessionData>,
206         (id_arg, name_arg, value_arg): super::StringArgTriple|
207         -> Box<dyn std::future::Future<Output = wasmtime::Result<i32>> + Send> {
208            Box::new(async move {
209                let user_id = caller.data().ctx().user_id;
210                let id = read_string_arg(&mut caller, id_arg)?;
211                let name = read_string_arg(&mut caller, name_arg)?;
212                let value = read_string_arg(&mut caller, value_arg)?;
213                run_set_transaction_tag(user_id, id, name, value).await
214            })
215        },
216    )?;
217    Ok(())
218}