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>
10where
11 Id: IdT,
12 Ops: BorshSerialize + BorshDeserialize,
13{
14 let header = borsh::to_vec(&header).expect("to_msg header serialize error");
15 let header_len = header.len();
18 let len = payload.len() + header_len;
19 let mut buffer = Vec::with_capacity(len);
20 #[allow(clippy::uninit_vec)]
21 unsafe {
22 buffer.set_len(len);
23 }
24 buffer[0..header_len].copy_from_slice(&header);
25 buffer[header_len..].copy_from_slice(payload);
26 let array = Uint8Array::from(&buffer[..]);
29 Ok(array.buffer())
30}
31
32#[derive(Debug, Clone, Copy, BorshSerialize, BorshDeserialize)]
33#[repr(u8)]
34#[borsh(use_discriminant = true)]
35pub enum MessageKind {
37 Notification = 0,
39 Request = 1,
41 Response = 2,
43}
44
45impl From<MessageKind> for u32 {
46 fn from(kind: MessageKind) -> u32 {
47 kind as u32
48 }
49}
50
51#[derive(Debug, BorshSerialize, BorshDeserialize)]
52pub struct BorshHeader<Id = Id64>
55where
56 Id: BorshSerialize + BorshDeserialize,
57{
58 pub kind: MessageKind,
60 pub id: Option<Id>,
62 pub op: Vec<u8>,
64}
65
66impl<Id> BorshHeader<Id>
67where
68 Id: BorshSerialize + BorshDeserialize,
69{
70 pub fn request<Ops>(id: Option<Id>, op: Ops) -> Self
73 where
74 Ops: OpsT,
75 {
76 BorshHeader {
77 id,
78 op: borsh::to_vec(&op).expect("request op serialize error"),
79 kind: MessageKind::Request,
80 }
81 }
82
83 pub fn response<Ops>(id: Option<Id>, op: Ops) -> Self
86 where
87 Ops: OpsT,
88 {
89 BorshHeader {
90 id,
91 op: borsh::to_vec(&op).expect("response op serialize error"),
92 kind: MessageKind::Response,
93 }
94 }
95
96 pub fn notification<Ops>(op: Ops) -> Self
99 where
100 Ops: OpsT,
101 {
102 BorshHeader {
103 id: None,
104 op: borsh::to_vec(&op).expect("notification op serialize error"),
105 kind: MessageKind::Notification,
106 }
107 }
108}
109
110#[derive(Debug)]
111pub struct BorshMessage<'data, Id = Id64>
114where
115 Id: BorshSerialize + BorshDeserialize + 'data,
116{
117 pub header: BorshHeader<Id>,
119 pub payload: &'data [u8],
121}
122
123impl<'data, Id> TryFrom<&'data Vec<u8>> for BorshMessage<'data, Id>
124where
125 Id: Debug + BorshSerialize + BorshDeserialize + 'data,
126{
127 type Error = Error;
128
129 fn try_from(src: &'data Vec<u8>) -> std::result::Result<Self, Self::Error> {
130 let v: BorshMessage<Id> = src[..].try_into()?;
131 Ok(v)
132 }
133}
134
135impl<'data, Id> TryFrom<&'data [u8]> for BorshMessage<'data, Id>
136where
137 Id: Debug + BorshSerialize + BorshDeserialize + 'data,
138{
139 type Error = Error;
140
141 fn try_from(src: &'data [u8]) -> std::result::Result<Self, Self::Error> {
142 let mut payload = src;
143 let header = BorshHeader::<Id>::deserialize(&mut payload)?;
144 let message = BorshMessage { header, payload };
145 Ok(message)
146 }
147}