1use core::convert::TryFrom;
2use core::ops::Deref;
3
4#[cfg(feature = "alloc")]
5use alloc::prelude::v1::*;
6
7use byteorder::{ByteOrder, NetworkEndian};
8use slice_ext::SplitBefore;
9
10use crate::base::{Base, BaseOptions, Body, Header};
11use crate::error::Error;
12use crate::options::Options;
13use crate::page::Page;
14use crate::types::*;
15
16use super::Common;
17use super::BUFF_SIZE;
18
19#[derive(Clone, Debug)]
21pub struct Response {
22 pub common: Common,
23 pub data: ResponseKind,
24}
25
26#[derive(Clone, PartialEq, Debug)]
28#[cfg_attr(feature = "strum", derive(strum_macros::Display))]
29pub enum ResponseKind {
30 Status(Status),
31 NodesFound(Id, Vec<(Id, Address, PublicKey)>),
32 ValuesFound(Id, Vec<Page>),
33 NoResult,
34 PullData(Id, Vec<Page>),
35}
36
37mod status {
38 pub const OK: u32 = 0x0000_0000;
39 pub const INVALID_REQUEST: u32 = 0x0000_0001;
40}
41
42#[derive(Clone, PartialEq, Debug)]
44pub enum Status {
45 Ok,
46 InvalidRequest,
47 Unknown(u32),
48}
49
50impl From<u32> for Status {
51 fn from(v: u32) -> Self {
52 match v {
53 status::OK => Status::Ok,
54 status::INVALID_REQUEST => Status::InvalidRequest,
55 _ => Status::Unknown(v),
56 }
57 }
58}
59
60impl Into<u32> for Status {
61 fn into(self) -> u32 {
62 match self {
63 Status::Ok => status::OK,
64 Status::InvalidRequest => status::INVALID_REQUEST,
65 Status::Unknown(v) => v,
66 }
67 }
68}
69
70impl Deref for Response {
71 type Target = Common;
72
73 fn deref(&self) -> &Common {
74 &self.common
75 }
76}
77
78impl Response {
79 pub fn new(from: Id, id: RequestId, data: ResponseKind, flags: Flags) -> Response {
80 let common = Common {
81 from,
82 id,
83 flags,
84 public_key: None,
85 remote_address: None,
86 };
87 Response { common, data }
88 }
89
90 pub fn flags(&mut self) -> &mut Flags {
91 &mut self.common.flags
92 }
93
94 pub fn with_remote_address(mut self, addr: Address) -> Self {
95 self.common.remote_address = Some(addr);
96 self
97 }
98
99 pub fn set_public_key(&mut self, pk: PublicKey) {
100 self.common.public_key = Some(pk);
101 }
102
103 pub fn with_public_key(mut self, pk: PublicKey) -> Self {
104 self.common.public_key = Some(pk);
105 self
106 }
107}
108
109#[cfg(nope)]
110impl fmt::Debug for ResponseKind {
111 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
112 match self {
113 ResponseKind::Status => write!(f, "status"),
114 ResponseKind::NodesFound(id, nodes) => {
115 write!(f, "NodesFound({:?}): [", id)?;
116 for n in nodes {
117 write!(f, "\n - {:?}", n)?;
118 }
119 writeln!(f, "]")
120 }
121 ResponseKind::ValuesFound(id, values) => {
122 write!(f, "ValuesFound({:?}): [", id)?;
123 for v in values {
124 write!(f, "\n - {:?}", v)?;
125 }
126 writeln!(f, "]")
127 }
128 ResponseKind::NoResult => write!(f, "NoResult"),
129 ResponseKind::PullData(id, values) => {
130 write!(f, "PullData({:?}): [", id)?;
131 for v in values {
132 write!(f, "\n - {:?}", v)?;
133 }
134 writeln!(f, "]")
135 }
136 }
137 }
138}
139
140impl PartialEq for Response {
141 fn eq(&self, b: &Self) -> bool {
142 self.from == b.from && self.flags == b.flags && self.data == b.data
143 }
144}
145
146impl Response {
147 pub fn convert<V>(base: Base, key_source: V) -> Result<Response, Error>
148 where
149 V: Fn(&Id) -> Option<PublicKey>,
150 {
151 let header = base.header();
152
153 let empty_body = vec![];
154 let body = match base.body() {
155 Body::Cleartext(d) => d,
156 Body::None => &empty_body,
157 Body::Encrypted(_e) => {
158 panic!("Attempting to convert encrypted object to response message")
159 }
160 };
161
162 let remote_address = None;
163
164 let _public_options = base.public_options().to_vec();
165 let kind = match MessageKind::try_from(header.kind()) {
168 Ok(k) => k,
169 Err(_) => return Err(Error::InvalidMessageKind),
170 };
171
172 let data = match kind {
173 MessageKind::Status => {
174 let status = NetworkEndian::read_u32(&body);
175 ResponseKind::Status(status.into())
176 }
177 MessageKind::NoResult => ResponseKind::NoResult,
178 MessageKind::NodesFound => {
179 let mut id = Id::default();
180 id.copy_from_slice(&body[..ID_LEN]);
181
182 let (options, _n) = Options::parse_vec(&body[ID_LEN..]).unwrap();
184
185 let nodes: Vec<_> = (&options[..])
186 .split_before(|o| match o {
187 Options::PeerId(_) => true,
188 _ => false,
189 })
190 .filter_map(|opts| {
191 let id = Base::peer_id_option(&opts);
192 let addr = Base::address_option(&opts);
193 let key = Base::pub_key_option(&opts);
194
195 match (id, addr, key) {
196 (Some(id), Some(addr), Some(key)) => Some((id, addr, key)),
197 _ => None,
199 }
200 })
201 .collect();
202
203 ResponseKind::NodesFound(id, nodes)
204 }
205 MessageKind::ValuesFound => {
206 let mut id = Id::default();
207 id.copy_from_slice(&body[0..ID_LEN]);
208
209 let pages = Page::decode_pages(&body[ID_LEN..], key_source).unwrap();
210
211 ResponseKind::ValuesFound(id, pages)
212 }
213 MessageKind::PullData => {
214 let mut id = Id::default();
215 id.copy_from_slice(&body[0..ID_LEN]);
216
217 let pages = Page::decode_pages(&body[ID_LEN..], key_source).unwrap();
218
219 ResponseKind::PullData(id, pages)
220 }
221 _ => {
222 error!(
223 "Error converting base object of kind {:?} to response message",
224 header.kind()
225 );
226 return Err(Error::InvalidMessageKind);
227 }
228 };
229
230 let public_key = base.public_key.clone();
232
233 let common = Common {
236 from: base.id().clone(),
237 id: header.index(),
238 flags: header.flags(),
239 public_key,
240 remote_address,
241 };
242 Ok(Response { common, data })
243 }
244}
245
246impl Into<Base> for Response {
247 fn into(self) -> Base {
248 let kind: MessageKind;
249 let body: Vec<u8>;
250
251 let mut buff = vec![0; BUFF_SIZE];
252
253 let mut base_options = BaseOptions::default();
254
255 match &self.data {
256 ResponseKind::Status(code) => {
257 kind = MessageKind::Status;
258 NetworkEndian::write_u32(&mut buff, code.clone().into());
259 body = (&buff[0..4]).to_vec();
260 }
261 ResponseKind::NoResult => {
262 kind = MessageKind::NoResult;
263 body = vec![];
265 }
266 ResponseKind::NodesFound(id, nodes) => {
267 kind = MessageKind::NodesFound;
268 (&mut buff[..ID_LEN]).copy_from_slice(&id);
269
270 let mut options = Vec::with_capacity(nodes.len() * 3);
272 for n in nodes {
273 options.push(Options::peer_id(n.0.clone()));
274 options.push(Options::address(n.1));
275 options.push(Options::pub_key(n.2.clone()));
276 }
277
278 let n = Options::encode_vec(&options, &mut buff[ID_LEN..]).unwrap();
280
281 body = buff[..ID_LEN + n].to_vec();
282 }
283 ResponseKind::ValuesFound(id, pages) => {
284 kind = MessageKind::ValuesFound;
285 (&mut buff[..ID_LEN]).copy_from_slice(&id);
286
287 let n = Page::encode_pages(&pages, &mut buff[ID_LEN..]).unwrap();
288
289 body = buff[..ID_LEN + n].to_vec();
290 }
291 ResponseKind::PullData(id, pages) => {
292 kind = MessageKind::PullData;
293 (&mut buff[..ID_LEN]).copy_from_slice(&id);
294
295 let n = Page::encode_pages(&pages, &mut buff[ID_LEN..]).unwrap();
296
297 body = buff[..ID_LEN + n].to_vec();
298 }
299 }
300
301 let header = Header {
303 kind: kind.into(),
304 index: self.common.id.clone(),
305 flags: self.common.flags,
306 ..Default::default()
307 };
308
309 base_options.public_key = self.common.public_key.clone();
311 if let Some(a) = self.remote_address {
312 base_options.append_public_option(Options::address(a));
313 }
314
315 Base::new(
317 self.common.from.clone(),
318 header,
319 Body::from(body),
320 base_options,
321 )
322 }
323}