1use anyhow::{Error, Result};
2use edn::query::ParsedQuery;
3
4use crate::ops::{QueryArg, TxOp};
5use crate::query::QueryResult;
6use crate::transaction::{TransactionResult, TxKey};
7
8#[allow(async_fn_in_trait)]
9pub trait SubmitNode {
10 async fn submit_tx<O: IntoTxOp>(&self, ops: Vec<O>) -> Result<TxKey, Error>;
11 async fn execute_tx<O: IntoTxOp>(&self, ops: Vec<O>) -> Result<TransactionResult, Error>;
12}
13
14pub trait IntoTxOp {
17 fn into_tx_op(self) -> Result<TxOp, Error>;
18}
19
20impl IntoTxOp for TxOp {
21 fn into_tx_op(self) -> Result<TxOp, Error> {
22 Ok(self)
23 }
24}
25
26impl IntoTxOp for &str {
27 fn into_tx_op(self) -> Result<TxOp, Error> {
28 self.parse()
29 }
30}
31
32impl IntoTxOp for String {
33 fn into_tx_op(self) -> Result<TxOp, Error> {
34 self.as_str().into_tx_op()
35 }
36}
37
38pub fn collect_tx_ops<O: IntoTxOp>(ops: Vec<O>) -> Result<Vec<TxOp>, Error> {
39 ops.into_iter().map(IntoTxOp::into_tx_op).collect()
40}
41
42pub trait IntoQuery {
43 fn into_query(self) -> Result<ParsedQuery, Error>;
44}
45
46impl IntoQuery for ParsedQuery {
47 fn into_query(self) -> Result<ParsedQuery, Error> {
48 Ok(self)
49 }
50}
51
52impl IntoQuery for &ParsedQuery {
54 fn into_query(self) -> Result<ParsedQuery, Error> {
55 Ok(self.clone())
56 }
57}
58
59impl IntoQuery for &str {
60 fn into_query(self) -> Result<ParsedQuery, Error> {
61 self.parse()
62 .map_err(|e| anyhow::anyhow!("EDN parse error: {}", e))
63 }
64}
65
66impl IntoQuery for String {
67 fn into_query(self) -> Result<ParsedQuery, Error> {
68 self.as_str().into_query()
69 }
70}
71
72#[allow(async_fn_in_trait)]
73pub trait Database {
74 async fn query(&self, query: impl IntoQuery) -> Result<QueryResult, Error>;
75
76 async fn query_with_args(
77 &self,
78 query: &ParsedQuery,
79 args: &[QueryArg],
80 ) -> Result<QueryResult, Error>;
81}
82
83#[allow(async_fn_in_trait)]
84pub trait QueryNode {
85 type DB: Database;
86 async fn db(&self) -> Result<Self::DB, Error>;
87 async fn db_as_of(&self, tx_key: TxKey) -> Result<Self::DB, Error>;
88}