workflow_nw/ipc/
messages.rs1use crate::ipc::error::Error;
2use crate::ipc::imports::*;
3use borsh::{BorshDeserialize, BorshSerialize};
4use js_sys::{ArrayBuffer, Uint8Array};
5use std::fmt::Debug;
6
7pub fn to_msg<Ops, Id>(header: BorshHeader<Id>, payload: &[u8]) -> Result<ArrayBuffer>
8where
9 Id: IdT,
10 Ops: BorshSerialize + BorshDeserialize,
11{
12 let header = borsh::to_vec(&header).expect("to_msg header serialize error");
13 let header_len = header.len();
16 let len = payload.len() + header_len;
17 let mut buffer = Vec::with_capacity(len);
18 #[allow(clippy::uninit_vec)]
19 unsafe {
20 buffer.set_len(len);
21 }
22 buffer[0..header_len].copy_from_slice(&header);
23 buffer[header_len..].copy_from_slice(payload);
24 let array = Uint8Array::from(&buffer[..]);
27 Ok(array.buffer())
28}
29
30#[derive(Debug, Clone, Copy, BorshSerialize, BorshDeserialize)]
31#[repr(u8)]
32#[borsh(use_discriminant = true)]
33pub enum MessageKind {
34 Notification = 0,
35 Request = 1,
36 Response = 2,
37}
38
39impl From<MessageKind> for u32 {
40 fn from(kind: MessageKind) -> u32 {
41 kind as u32
42 }
43}
44
45#[derive(Debug, BorshSerialize, BorshDeserialize)]
46pub struct BorshHeader<Id = Id64>
47where
48 Id: BorshSerialize + BorshDeserialize,
49{
50 pub kind: MessageKind,
51 pub id: Option<Id>,
52 pub op: Vec<u8>,
53}
54
55impl<Id> BorshHeader<Id>
56where
57 Id: BorshSerialize + BorshDeserialize,
58{
59 pub fn request<Ops>(id: Option<Id>, op: Ops) -> Self
60 where
61 Ops: OpsT,
62 {
63 BorshHeader {
64 id,
65 op: borsh::to_vec(&op).expect("request op serialize error"),
66 kind: MessageKind::Request,
67 }
68 }
69
70 pub fn response<Ops>(id: Option<Id>, op: Ops) -> Self
71 where
72 Ops: OpsT,
73 {
74 BorshHeader {
75 id,
76 op: borsh::to_vec(&op).expect("response op serialize error"),
77 kind: MessageKind::Response,
78 }
79 }
80
81 pub fn notification<Ops>(op: Ops) -> Self
82 where
83 Ops: OpsT,
84 {
85 BorshHeader {
86 id: None,
87 op: borsh::to_vec(&op).expect("notification op serialize error"),
88 kind: MessageKind::Notification,
89 }
90 }
91}
92
93#[derive(Debug)]
94pub struct BorshMessage<'data, Id = Id64>
95where
96 Id: BorshSerialize + BorshDeserialize + 'data,
97{
98 pub header: BorshHeader<Id>,
99 pub payload: &'data [u8],
100}
101
102impl<'data, Id> TryFrom<&'data Vec<u8>> for BorshMessage<'data, Id>
103where
104 Id: Debug + BorshSerialize + BorshDeserialize + 'data,
105{
106 type Error = Error;
107
108 fn try_from(src: &'data Vec<u8>) -> std::result::Result<Self, Self::Error> {
109 let v: BorshMessage<Id> = src[..].try_into()?;
110 Ok(v)
111 }
112}
113
114impl<'data, Id> TryFrom<&'data [u8]> for BorshMessage<'data, Id>
115where
116 Id: Debug + BorshSerialize + BorshDeserialize + 'data,
117{
118 type Error = Error;
119
120 fn try_from(src: &'data [u8]) -> std::result::Result<Self, Self::Error> {
121 let mut payload = src;
122 let header = BorshHeader::<Id>::deserialize(&mut payload)?;
123 let message = BorshMessage { header, payload };
124 Ok(message)
125 }
126}