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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use super::*;
use crate::error::ProtocolError;
use channel_protocol::ChannelMessage;
use log::info;
use serde_cbor::ser;
use std::collections::HashMap;
pub fn from_cbor(message: &ChannelMessage) -> Result<Message, ProtocolError> {
let mut process_list: Option<HashMap<u32, (String, u32)>> = None;
if let Some(Value::Object(raw_list)) = message.payload.get(0) {
process_list = Some(
raw_list
.into_iter()
.map(|(channel, data)| (channel.as_u64(), data.as_array()))
.filter(|(channel, data)| channel.is_some() && data.is_some())
.map(|(channel, data)| {
let path = data.unwrap().get(0).and_then(|v| v.as_string());
let pid = data.unwrap().get(1).and_then(|v| v.as_u64());
(channel, path, pid)
})
.filter(|(_channel, path, pid)| path.is_some() && pid.is_some())
.map(|(channel, path, pid)| {
(
channel.unwrap() as u32,
(path.unwrap().to_owned(), pid.unwrap() as u32),
)
})
.collect::<HashMap<u32, (String, u32)>>(),
)
};
Ok(Message::List {
channel_id: message.channel_id,
process_list,
})
}
pub fn to_cbor(
channel_id: u32,
process_list: Option<HashMap<u32, (String, u32)>>,
) -> Result<Vec<u8>, ProtocolError> {
info!("-> {{ {}, list, '{:?}' }}", channel_id, process_list);
Ok(
ser::to_vec_packed(&(channel_id, "list", process_list)).map_err(|err| {
ProtocolError::MessageCreationError {
message: "list".to_owned(),
err,
}
})?,
)
}
#[cfg(test)]
mod tests {
use super::*;
use channel_protocol;
use serde_cbor::de;
#[test]
fn create_parse_message() {
let channel_id = 13;
let mut process_list: HashMap<u32, (String, u32)> = HashMap::new();
process_list.insert(10, ("/bin/bash".to_owned(), 99));
process_list.insert(12, ("ls".to_owned(), 1132));
let raw = to_cbor(channel_id, Some(process_list.to_owned())).unwrap();
let parsed = channel_protocol::parse_message(de::from_slice(&raw).unwrap()).unwrap();
let msg = parse_message(&parsed);
assert_eq!(
msg.unwrap(),
Message::List {
channel_id: channel_id,
process_list: Some(process_list),
}
);
}
#[test]
fn create_parse_message_empty() {
let channel_id = 13;
let raw = to_cbor(channel_id, None).unwrap();
let parsed = channel_protocol::parse_message(de::from_slice(&raw).unwrap()).unwrap();
let msg = parse_message(&parsed);
assert_eq!(
msg.unwrap(),
Message::List {
channel_id: channel_id,
process_list: None,
}
);
}
}