1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
use crate::app::App;
use crate::types::{Command, Error, HidInterchange, Message};
use interchange::{Interchange, Responder};
pub struct Dispatch {
responder: Responder<HidInterchange>,
}
impl Dispatch {
pub fn new(responder: Responder<HidInterchange>) -> Dispatch {
Dispatch { responder }
}
fn find_app<'a, 'b>(
command: Command,
apps: &'a mut [&'b mut dyn App],
) -> Option<&'a mut &'b mut dyn App> {
apps.iter_mut()
.find(|app| app.commands().contains(&command))
}
#[inline(never)]
fn reply_with_error(&mut self, error: Error) {
self.responder.respond(&Err(error)).expect("cant respond");
}
#[inline(never)]
fn call_app(&mut self, app: &mut dyn App, command: Command, request: &Message) {
let tuple: &mut (Command, Message) = unsafe { (&mut *self.responder.interchange.get()).rq_mut() };
let response_buffer = &mut tuple.1;
response_buffer.clear();
if let Err(error) = app.call(command, request, response_buffer) {
self.reply_with_error(error)
} else {
let response = Ok(response_buffer.clone());
self.responder.respond(&response).expect("responder failed");
}
}
#[inline(never)]
pub fn poll<'a>(&mut self, apps: &mut [&'a mut dyn App]) -> bool {
let maybe_request = self.responder.take_request();
if let Some((command, message)) = maybe_request {
if let Some(app) = Self::find_app(command, apps) {
self.call_app(*app, command, &message);
} else {
self.reply_with_error(Error::InvalidCommand);
}
}
self.responder.state() == interchange::State::Responded
}
}