1use core::convert::TryFrom;
2use core::ops::Deref;
3
4#[cfg(feature = "alloc")]
5use alloc::prelude::v1::*;
6
7use crate::base::{Base, BaseOptions, Body, Header};
8use crate::error::Error;
9use crate::options::Options;
10use crate::page::Page;
11use crate::types::*;
12
13use super::Common;
14use super::BUFF_SIZE;
15
16#[derive(Clone, Debug)]
17pub struct Request {
18 pub common: Common,
19 pub data: RequestKind,
20}
21
22impl Deref for Request {
23 type Target = Common;
24
25 fn deref(&self) -> &Common {
26 &self.common
27 }
28}
29
30#[derive(Clone, PartialEq, Debug)]
31#[cfg_attr(feature = "strum", derive(strum_macros::Display))]
32pub enum RequestKind {
33 Hello,
34 Ping,
35 FindNode(Id),
36 FindValue(Id),
37 Store(Id, Vec<Page>),
38
39 Subscribe(Id),
40 Unsubscribe(Id),
41 Query(Id),
42 PushData(Id, Vec<Page>),
43
44 Register(Id, Vec<Page>),
45 Unregister(Id),
46}
47
48impl Request {
49 pub fn new(from: Id, request_id: u16, data: RequestKind, flags: Flags) -> Request {
50 let common = Common {
51 from,
52 id: request_id,
53 flags,
54 public_key: None,
55 remote_address: None,
56 };
57 Request { common, data }
58 }
59
60 pub fn flags(&mut self) -> &mut Flags {
61 &mut self.common.flags
62 }
63
64 pub fn set_public_key(&mut self, pk: PublicKey) {
65 self.common.public_key = Some(pk);
66 }
67
68 pub fn with_public_key(mut self, pk: PublicKey) -> Self {
69 self.common.public_key = Some(pk);
70 self
71 }
72}
73
74impl PartialEq for Request {
75 fn eq(&self, b: &Self) -> bool {
76 self.from == b.from && self.flags == b.flags && self.data == b.data
77 }
78}
79
80impl Request {
81 pub fn convert<V>(base: Base, key_source: V) -> Result<Request, Error>
82 where
83 V: Fn(&Id) -> Option<PublicKey>,
84 {
85 let header = base.header();
86
87 let empty_body = vec![];
88 let body = match base.body() {
89 Body::Cleartext(d) => d,
90 Body::None => &empty_body,
91 Body::Encrypted(_e) => {
92 panic!("Attempting to convert encrypted object to response message")
93 }
94 };
95
96 let remote_address = None;
97 let _public_options = base.public_options().to_vec();
98 let kind = match MessageKind::try_from(header.kind()) {
101 Ok(k) => k,
102 Err(_) => return Err(Error::InvalidMessageKind),
103 };
104
105 let data = match kind {
106 MessageKind::Hello => RequestKind::Hello,
107 MessageKind::Ping => RequestKind::Ping,
108 MessageKind::FindNodes => {
109 let mut id = Id::default();
110 id.copy_from_slice(&body[0..ID_LEN]);
111 RequestKind::FindNode(id)
112 }
113 MessageKind::FindValues => {
114 let mut id = Id::default();
115 id.copy_from_slice(&body[0..ID_LEN]);
116 RequestKind::FindValue(id)
117 }
118 MessageKind::Subscribe => {
119 let mut id = Id::default();
120 id.copy_from_slice(&body[0..ID_LEN]);
121 RequestKind::Subscribe(id)
122 }
123 MessageKind::Query => {
124 let mut id = Id::default();
125 id.copy_from_slice(&body[0..ID_LEN]);
126 RequestKind::Query(id)
127 }
128 MessageKind::Store => {
129 let mut id = Id::default();
130 id.copy_from_slice(&body[0..ID_LEN]);
131
132 let pages = Page::decode_pages(&body[ID_LEN..], key_source).unwrap();
135
136 RequestKind::Store(id, pages)
137 }
138 MessageKind::PushData => {
139 let mut id = Id::default();
140 id.copy_from_slice(&body[0..ID_LEN]);
141
142 let pages = Page::decode_pages(&body[ID_LEN..], key_source).unwrap();
143
144 RequestKind::PushData(id, pages)
145 }
146 MessageKind::Register => {
147 let mut id = Id::default();
148 id.copy_from_slice(&body[0..ID_LEN]);
149
150 let pages = Page::decode_pages(&body[ID_LEN..], key_source).unwrap();
151
152 RequestKind::Register(id, pages)
153 }
154 MessageKind::Unregister => {
155 let mut id = Id::default();
156 id.copy_from_slice(&body[0..ID_LEN]);
157
158 RequestKind::Unregister(id)
159 }
160 _ => {
161 error!(
162 "Error converting base object of kind {:?} to request message",
163 header.kind()
164 );
165 return Err(Error::InvalidMessageKind);
166 }
167 };
168
169 let public_key = base.public_key.clone();
171 let common = Common {
174 from: base.id().clone(),
175 id: header.index(),
176 flags: header.flags(),
177 public_key,
178 remote_address,
179 };
180 Ok(Request { common, data })
181 }
182}
183
184impl Into<Base> for Request {
187 fn into(self) -> Base {
188 let kind: MessageKind;
189 let body;
190
191 let mut options = BaseOptions::default();
192
193 match &self.data {
194 RequestKind::Hello => {
195 kind = MessageKind::Hello;
196 body = vec![];
197 }
198 RequestKind::Ping => {
199 kind = MessageKind::Ping;
200 body = vec![];
201 }
202 RequestKind::FindNode(id) => {
203 kind = MessageKind::FindNodes;
204 body = id.to_vec();
205 }
206 RequestKind::FindValue(id) => {
207 kind = MessageKind::FindValues;
208 body = id.to_vec();
209 }
210 RequestKind::Store(id, pages) => {
211 kind = MessageKind::Store;
212
213 let mut buff = vec![0u8; BUFF_SIZE];
214 (&mut buff[..ID_LEN]).copy_from_slice(id);
215
216 let i = Page::encode_pages(pages, &mut buff[ID_LEN..]).unwrap();
217
218 body = buff[..ID_LEN + i].to_vec();
219 }
220 RequestKind::Subscribe(id) => {
221 kind = MessageKind::Subscribe;
222 body = id.to_vec();
223 }
224 RequestKind::Unsubscribe(id) => {
225 kind = MessageKind::Unsubscribe;
226 body = id.to_vec();
227 }
228 RequestKind::Query(id) => {
229 kind = MessageKind::Query;
230 body = id.to_vec();
231 }
232 RequestKind::PushData(id, pages) => {
233 kind = MessageKind::PushData;
234
235 let mut buff = vec![0u8; BUFF_SIZE];
236 (&mut buff[..ID_LEN]).copy_from_slice(id);
237
238 let i = Page::encode_pages(pages, &mut buff[ID_LEN..]).unwrap();
239
240 body = buff[..ID_LEN + i].to_vec();
241 }
242 RequestKind::Register(id, pages) => {
243 kind = MessageKind::Register;
244
245 let mut buff = vec![0u8; BUFF_SIZE];
246 (&mut buff[..ID_LEN]).copy_from_slice(id);
247
248 let i = Page::encode_pages(pages, &mut buff[ID_LEN..]).unwrap();
249
250 body = buff[..ID_LEN + i].to_vec();
251 }
252 RequestKind::Unregister(id) => {
253 kind = MessageKind::Unregister;
254 body = id.to_vec();
255 }
256 }
257
258 let header = Header {
260 kind: kind.into(),
261 flags: self.flags,
262 index: self.id,
263 ..Default::default()
264 };
265
266 options.public_key = self.public_key.clone();
268 if let Some(a) = self.remote_address {
269 options.append_public_option(Options::address(a));
270 }
271
272 Base::new(self.from.clone(), header, Body::from(body), options)
274 }
275}
276
277#[cfg(nope)]
278impl fmt::Debug for RequestKind {
279 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
280 match self {
281 RequestKind::Hello => write!(f, "status"),
282 RequestKind::Ping => write!(f, "Ping"),
283 RequestKind::FindNode(id) => write!(f, "FindNode ({:?})", id),
284 RequestKind::FindValue(id) => write!(f, "FindValue ({:?})", id),
285 RequestKind::Store(id, values) => {
286 write!(f, "Store({:?}): [", id)?;
287 for v in values {
288 write!(f, "\n - {:?}", v)?;
289 }
290 writeln!(f, "]")
291 }
292 }
293 }
294}