1mod sint;
4mod uint;
5mod dec;
6mod str;
7mod bin;
8mod vec;
9mod map;
10mod ext;
11
12pub use self::sint::{write_nfix, write_i8, write_i16, write_i32, write_i64, write_sint};
13pub use self::uint::{write_pfix, write_u8, write_u16, write_u32, write_u64, write_uint};
14pub use self::dec::{write_f32, write_f64};
15pub use self::str::{write_str_len, write_str};
16pub use self::bin::{write_bin_len, write_bin};
17
18use std::error;
19use std::fmt::{self, Display, Formatter};
20use std::io::Write;
21
22use byteorder::{self, WriteBytesExt};
23
24use Marker;
25
26pub type Error = ::std::io::Error;
28
29struct MarkerWriteError(Error);
31
32impl From<Error> for MarkerWriteError {
33 fn from(err: Error) -> MarkerWriteError {
34 MarkerWriteError(err)
35 }
36}
37
38impl From<MarkerWriteError> for Error {
39 fn from(err: MarkerWriteError) -> Error {
40 match err {
41 MarkerWriteError(err) => err
42 }
43 }
44}
45
46fn write_marker<W: Write>(wr: &mut W, marker: Marker) -> Result<(), MarkerWriteError> {
48 wr.write_u8(marker.to_u8()).map_err(MarkerWriteError)
49}
50
51struct DataWriteError(Error);
53
54impl From<Error> for DataWriteError {
55 fn from(err: Error) -> DataWriteError {
56 DataWriteError(err)
57 }
58}
59
60impl From<DataWriteError> for Error {
61 fn from(err: DataWriteError) -> Error {
62 err.0
63 }
64}
65
66pub fn write_nil<W: Write>(wr: &mut W) -> Result<(), Error> {
84 write_marker(wr, Marker::Null).map_err(From::from)
85}
86
87pub fn write_bool<W: Write>(wr: &mut W, val: bool) -> Result<(), Error> {
97 let marker = if val {
98 Marker::True
99 } else {
100 Marker::False
101 };
102
103 write_marker(wr, marker).map_err(From::from)
104}
105
106fn write_data_u8<W: Write>(wr: &mut W, val: u8) -> Result<(), DataWriteError> {
107 wr.write_u8(val).map_err(DataWriteError)
108}
109
110fn write_data_u16<W: Write>(wr: &mut W, val: u16) -> Result<(), DataWriteError> {
111 wr.write_u16::<byteorder::BigEndian>(val).map_err(DataWriteError)
112}
113
114fn write_data_u32<W: Write>(wr: &mut W, val: u32) -> Result<(), DataWriteError> {
115 wr.write_u32::<byteorder::BigEndian>(val).map_err(DataWriteError)
116}
117
118fn write_data_u64<W: Write>(wr: &mut W, val: u64) -> Result<(), DataWriteError> {
119 wr.write_u64::<byteorder::BigEndian>(val).map_err(DataWriteError)
120}
121
122fn write_data_i8<W: Write>(wr: &mut W, val: i8) -> Result<(), DataWriteError> {
123 wr.write_i8(val).map_err(DataWriteError)
124}
125
126fn write_data_i16<W: Write>(wr: &mut W, val: i16) -> Result<(), DataWriteError> {
127 wr.write_i16::<byteorder::BigEndian>(val).map_err(DataWriteError)
128}
129
130fn write_data_i32<W: Write>(wr: &mut W, val: i32) -> Result<(), DataWriteError> {
131 wr.write_i32::<byteorder::BigEndian>(val).map_err(DataWriteError)
132}
133
134fn write_data_i64<W: Write>(wr: &mut W, val: i64) -> Result<(), DataWriteError> {
135 wr.write_i64::<byteorder::BigEndian>(val).map_err(DataWriteError)
136}
137
138fn write_data_f32<W: Write>(wr: &mut W, val: f32) -> Result<(), DataWriteError> {
139 wr.write_f32::<byteorder::BigEndian>(val).map_err(DataWriteError)
140}
141
142fn write_data_f64<W: Write>(wr: &mut W, val: f64) -> Result<(), DataWriteError> {
143 wr.write_f64::<byteorder::BigEndian>(val).map_err(DataWriteError)
144}
145
146#[derive(Debug)]
148pub enum ValueWriteError {
149 InvalidMarkerWrite(Error),
151 InvalidDataWrite(Error),
153}
154
155impl From<MarkerWriteError> for ValueWriteError {
156 fn from(err: MarkerWriteError) -> ValueWriteError {
157 match err {
158 MarkerWriteError(err) => ValueWriteError::InvalidMarkerWrite(err),
159 }
160 }
161}
162
163impl From<DataWriteError> for ValueWriteError {
164 fn from(err: DataWriteError) -> ValueWriteError {
165 match err {
166 DataWriteError(err) => ValueWriteError::InvalidDataWrite(err),
167 }
168 }
169}
170
171impl From<ValueWriteError> for Error {
172 fn from(err: ValueWriteError) -> Error {
173 match err {
174 ValueWriteError::InvalidMarkerWrite(err) |
175 ValueWriteError::InvalidDataWrite(err) => err,
176 }
177 }
178}
179
180impl error::Error for ValueWriteError {
181 fn description(&self) -> &str {
182 "error while writing multi-byte MessagePack value"
183 }
184
185 fn cause(&self) -> Option<&error::Error> {
186 match *self {
187 ValueWriteError::InvalidMarkerWrite(ref err) |
188 ValueWriteError::InvalidDataWrite(ref err) => Some(err),
189 }
190 }
191}
192
193impl Display for ValueWriteError {
194 fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
195 error::Error::description(self).fmt(f)
196 }
197}
198
199pub fn write_array_len<W: Write>(wr: &mut W, len: u32) -> Result<Marker, ValueWriteError> {
207 let marker = if len < 16 {
208 try!(write_marker(wr, Marker::FixArray(len as u8)));
209 Marker::FixArray(len as u8)
210 } else if len < 65536 {
211 try!(write_marker(wr, Marker::Array16));
212 try!(write_data_u16(wr, len as u16));
213 Marker::Array16
214 } else {
215 try!(write_marker(wr, Marker::Array32));
216 try!(write_data_u32(wr, len));
217 Marker::Array32
218 };
219
220 Ok(marker)
221}
222
223pub fn write_map_len<W: Write>(wr: &mut W, len: u32) -> Result<Marker, ValueWriteError> {
231 let marker = if len < 16 {
232 try!(write_marker(wr, Marker::FixMap(len as u8)));
233 Marker::FixMap(len as u8)
234 } else if len < 65536 {
235 try!(write_marker(wr, Marker::Map16));
236 try!(write_data_u16(wr, len as u16));
237 Marker::Map16
238 } else {
239 try!(write_marker(wr, Marker::Map32));
240 try!(write_data_u32(wr, len));
241 Marker::Map32
242 };
243
244 Ok(marker)
245}
246
247pub fn write_ext_meta<W: Write>(wr: &mut W, len: u32, ty: i8) -> Result<Marker, ValueWriteError> {
260 assert!(ty >= 0);
261
262 let marker = match len {
263 1 => {
264 try!(write_marker(wr, Marker::FixExt1));
265 Marker::FixExt1
266 }
267 2 => {
268 try!(write_marker(wr, Marker::FixExt2));
269 Marker::FixExt2
270 }
271 4 => {
272 try!(write_marker(wr, Marker::FixExt4));
273 Marker::FixExt4
274 }
275 8 => {
276 try!(write_marker(wr, Marker::FixExt8));
277 Marker::FixExt8
278 }
279 16 => {
280 try!(write_marker(wr, Marker::FixExt16));
281 Marker::FixExt16
282 }
283 len if len < 256 => {
284 try!(write_marker(wr, Marker::Ext8));
285 try!(write_data_u8(wr, len as u8));
286 Marker::Ext8
287 }
288 len if len < 65536 => {
289 try!(write_marker(wr, Marker::Ext16));
290 try!(write_data_u16(wr, len as u16));
291 Marker::Ext16
292 }
293 len => {
294 try!(write_marker(wr, Marker::Ext32));
295 try!(write_data_u32(wr, len));
296 Marker::Ext32
297 }
298 };
299
300 try!(write_data_i8(wr, ty));
301
302 Ok(marker)
303}