1use errors::*;
2use rmpv::{decode, encode, Integer, Utf8String, Value};
3use std::convert::From;
4use std::io::{self, Read};
5
6#[derive(PartialEq, Clone, Debug)]
9pub enum Message {
10 Request(Request),
11 Response(Response),
12 Notification(Notification),
13}
14
15#[derive(PartialEq, Clone, Debug)]
22pub struct Request {
23 pub id: u32,
26 pub method: String,
28 pub params: Vec<Value>,
30}
31
32#[derive(PartialEq, Clone, Debug)]
37pub struct Response {
38 pub id: u32,
40 pub result: Result<Value, Value>,
42}
43
44#[derive(PartialEq, Clone, Debug)]
51pub struct Notification {
52 pub method: String,
54 pub params: Vec<Value>,
56}
57
58const REQUEST_MESSAGE: u64 = 0;
59const RESPONSE_MESSAGE: u64 = 1;
60const NOTIFICATION_MESSAGE: u64 = 2;
61
62impl Message {
63 pub fn decode<R>(rd: &mut R) -> Result<Message, DecodeError>
64 where
65 R: Read,
66 {
67 let msg = decode::value::read_value(rd)?;
68 if let Value::Array(ref array) = msg {
69 if array.len() < 3 {
70 return Err(DecodeError::Invalid);
72 }
73 if let Value::Integer(msg_type) = array[0] {
74 match msg_type.as_u64() {
75 Some(REQUEST_MESSAGE) => {
76 return Ok(Message::Request(Request::decode(array)?));
77 }
78 Some(RESPONSE_MESSAGE) => {
79 return Ok(Message::Response(Response::decode(array)?));
80 }
81 Some(NOTIFICATION_MESSAGE) => {
82 return Ok(Message::Notification(Notification::decode(array)?));
83 }
84 _ => {
85 return Err(DecodeError::Invalid);
86 }
87 }
88 } else {
89 return Err(DecodeError::Invalid);
90 }
91 } else {
92 return Err(DecodeError::Invalid);
93 }
94 }
95
96 pub fn as_value(&self) -> Value {
97 match *self {
98 Message::Request(Request {
99 id,
100 ref method,
101 ref params,
102 }) => Value::Array(vec![
103 Value::Integer(Integer::from(REQUEST_MESSAGE)),
104 Value::Integer(Integer::from(id)),
105 Value::String(Utf8String::from(method.as_str())),
106 Value::Array(params.clone()),
107 ]),
108 Message::Response(Response { id, ref result }) => {
109 let (error, result) = match *result {
110 Ok(ref result) => (Value::Nil, result.to_owned()),
111 Err(ref err) => (err.to_owned(), Value::Nil),
112 };
113 Value::Array(vec![
114 Value::Integer(Integer::from(RESPONSE_MESSAGE)),
115 Value::Integer(Integer::from(id)),
116 error,
117 result,
118 ])
119 }
120 Message::Notification(Notification {
121 ref method,
122 ref params,
123 }) => Value::Array(vec![
124 Value::Integer(Integer::from(NOTIFICATION_MESSAGE)),
125 Value::String(Utf8String::from(method.as_str())),
126 Value::Array(params.to_owned()),
127 ]),
128 }
129 }
130
131 pub fn pack(&self) -> io::Result<Vec<u8>> {
132 let mut bytes = vec![];
133 encode::write_value(&mut bytes, &self.as_value())?;
134 Ok(bytes)
135 }
136}
137
138impl Notification {
139 fn decode(array: &[Value]) -> Result<Self, DecodeError> {
140 if array.len() < 3 {
141 return Err(DecodeError::Invalid);
142 }
143
144 let method = if let Value::String(ref method) = array[1] {
145 method
146 .as_str()
147 .and_then(|s| Some(s.to_string()))
148 .ok_or(DecodeError::Invalid)?
149 } else {
150 return Err(DecodeError::Invalid);
151 };
152
153 let params = if let Value::Array(ref params) = array[2] {
154 params.clone()
155 } else {
156 return Err(DecodeError::Invalid);
157 };
158
159 Ok(Notification { method, params })
160 }
161}
162
163impl Request {
164 fn decode(array: &[Value]) -> Result<Self, DecodeError> {
165 if array.len() < 4 {
166 return Err(DecodeError::Invalid);
167 }
168
169 let id = if let Value::Integer(id) = array[1] {
170 id.as_u64()
171 .and_then(|id| Some(id as u32))
172 .ok_or(DecodeError::Invalid)?
173 } else {
174 return Err(DecodeError::Invalid);
175 };
176
177 let method = if let Value::String(ref method) = array[2] {
178 method
179 .as_str()
180 .and_then(|s| Some(s.to_string()))
181 .ok_or(DecodeError::Invalid)?
182 } else {
183 return Err(DecodeError::Invalid);
184 };
185
186 let params = if let Value::Array(ref params) = array[3] {
187 params.clone()
188 } else {
189 return Err(DecodeError::Invalid);
190 };
191
192 Ok(Request { id, method, params })
193 }
194}
195
196impl Response {
197 fn decode(array: &[Value]) -> Result<Self, DecodeError> {
198 if array.len() < 2 {
199 return Err(DecodeError::Invalid);
200 }
201
202 let id = if let Value::Integer(id) = array[1] {
203 id.as_u64()
204 .and_then(|id| Some(id as u32))
205 .ok_or(DecodeError::Invalid)?
206 } else {
207 return Err(DecodeError::Invalid);
208 };
209
210 match array[2] {
211 Value::Nil => Ok(Response {
212 id,
213 result: Ok(array[3].clone()),
214 }),
215 ref error => Ok(Response {
216 id,
217 result: Err(error.clone()),
218 }),
219 }
220 }
221}
222
223#[test]
224fn test_decode_request() {
225 let valid = Message::Request(Request {
226 id: 1234,
227 method: "dummy".to_string(),
228 params: Vec::new(),
229 });
230 let bytes = valid.pack().unwrap();
231
232 {
234 let mut buf = io::Cursor::new(&bytes);
235 assert_eq!(valid, Message::decode(&mut buf).unwrap());
236 }
237
238 {
240 let bytes = Vec::from(&bytes[0..bytes.len() - 1]);
241 let mut buf = io::Cursor::new(&bytes);
242 assert!(match Message::decode(&mut buf) {
243 Err(DecodeError::Truncated) => true,
244 _ => false,
245 });
246 }
247
248 {
250 let mut bytes = Vec::from(&bytes[..]);
251 bytes[1] = 5;
252 let mut buf = io::Cursor::new(&bytes);
253 assert!(match Message::decode(&mut buf) {
254 Err(DecodeError::Invalid) => true,
255 _ => false,
256 });
257 }
258}