Skip to main content

musdk_common/
incoming_message.rs

1pub mod db;
2pub mod storage;
3
4use std::{
5    borrow::Cow,
6    io::{Read, Write},
7};
8
9use borsh::{BorshDeserialize, BorshSerialize};
10use num_derive::FromPrimitive;
11use num_traits::FromPrimitive;
12
13use crate::function::*;
14use crate::http_client;
15use db::*;
16use storage::*;
17
18#[derive(FromPrimitive)]
19#[repr(u16)]
20enum IncomingMessageKind {
21    // Runtime messages
22    ExecuteFunction = 1,
23
24    // DB Messages
25    DbError = 1001,
26    SingleResult = 1002,
27    ListResult = 1003,
28    KeyValueListResult = 1004,
29    TableKeyListResult = 1005,
30    TableKeyValueListResult = 1006,
31    EmptyResult = 1007,
32    CasResult = 1008,
33
34    // Storage messages
35    StorageError = 2001,
36    StorageGetResult = 2002,
37    StorageEmptyResult = 2003,
38    ObjectListResult = 2004,
39
40    // Http Client
41    HttpResponse = 3001,
42}
43
44#[derive(Debug, BorshDeserialize, BorshSerialize)]
45pub struct ExecuteFunction<'a> {
46    pub function: Cow<'a, str>,
47    pub request: Request<'a>,
48}
49
50pub type HttpResponse<'a> = Result<http_client::Response<'a>, http_client::error::Error>;
51
52#[derive(Debug)]
53pub enum IncomingMessage<'a> {
54    // Runtime messages
55    ExecuteFunction(ExecuteFunction<'a>),
56
57    // DB messages
58    DbError(DbError<'a>),
59    SingleResult(SingleResult<'a>),
60    ListResult(ListResult<'a>),
61    KeyValueListResult(KeyValueListResult<'a>),
62    TableKeyListResult(TableKeyListResult<'a>),
63    TableKeyValueListResult(TableKeyValueListResult<'a>),
64    EmptyResult(EmptyResult),
65    CasResult(CasResult<'a>),
66
67    // Storage messages
68    StorageError(StorageError<'a>),
69    StorageGetResult(StorageGetResult<'a>),
70    StorageEmptyResult(StorageEmptyResult),
71    ObjectListResult(ObjectListResult<'a>),
72
73    // Http client
74    HttpResponse(HttpResponse<'a>),
75}
76
77macro_rules! read_cases {
78    ($kind: ident, $reader: ident, [$($case: ident),+] * $lf: lifetime, [$($unit_case: ident),*]) => {
79        match IncomingMessageKind::from_u16($kind) {
80            $(Some(IncomingMessageKind::$case) => {
81                let message: $case<$lf> = BorshDeserialize::deserialize_reader($reader)?;
82                Ok(Self::$case(message))
83            })+
84
85            $(Some(IncomingMessageKind::$unit_case) => {
86                let message: $unit_case = BorshDeserialize::deserialize_reader($reader)?;
87                Ok(Self::$unit_case(message))
88            })*
89
90            None => Err(
91                std::io::Error::new(
92                    std::io::ErrorKind::InvalidData,
93                    format!("Unknown incoming message code: {}", $kind)
94                )
95            ),
96        }
97    };
98}
99
100macro_rules! write_cases {
101    ($self: ident, $writer: ident, [$($case: ident),+]) => {
102        match $self {
103            $(IncomingMessage::$case(x) => {
104                (IncomingMessageKind::$case as u16).serialize($writer)?;
105                x.serialize($writer)?;
106            })+
107        }
108    };
109}
110
111impl<'a> IncomingMessage<'a> {
112    pub fn read(reader: &mut impl Read) -> std::io::Result<Self> {
113        let kind: u16 = BorshDeserialize::deserialize_reader(reader)?;
114
115        read_cases!(
116            kind,
117            reader,
118            [
119                ExecuteFunction,
120                DbError,
121                SingleResult,
122                ListResult,
123                KeyValueListResult,
124                TableKeyListResult,
125                TableKeyValueListResult,
126                CasResult,
127                StorageError,
128                StorageGetResult,
129                ObjectListResult,
130                HttpResponse
131            ] * 'static,
132            [EmptyResult, StorageEmptyResult]
133        )
134    }
135
136    pub fn write(&self, writer: &mut impl Write) -> std::io::Result<()> {
137        write_cases!(
138            self,
139            writer,
140            [
141                ExecuteFunction,
142                DbError,
143                SingleResult,
144                ListResult,
145                KeyValueListResult,
146                TableKeyListResult,
147                TableKeyValueListResult,
148                EmptyResult,
149                CasResult,
150                StorageError,
151                StorageGetResult,
152                StorageEmptyResult,
153                ObjectListResult,
154                HttpResponse
155            ]
156        );
157
158        Ok(())
159    }
160}