1 use std::io::Write;
2 
3 use rmp::encode::{
4     write_array_len, write_bin, write_bool, write_ext_meta, write_f32, write_f64, write_map_len,
5     write_nil, write_sint, write_str, write_uint,
6 };
7 
8 use super::Error;
9 use crate::{IntPriv, Integer, Utf8String, Value};
10 
11 /// Encodes and attempts to write the most efficient representation of the given Value.
12 ///
13 /// # Note
14 ///
15 /// All instances of `ErrorKind::Interrupted` are handled by this function and the underlying
16 /// operation is retried.
write_value<W>(wr: &mut W, val: &Value) -> Result<(), Error> where W: Write17 pub fn write_value<W>(wr: &mut W, val: &Value) -> Result<(), Error>
18     where W: Write
19 {
20     match *val {
21         Value::Nil => {
22             write_nil(wr).map_err(Error::InvalidMarkerWrite)?;
23         }
24         Value::Boolean(val) => {
25             write_bool(wr, val).map_err(Error::InvalidMarkerWrite)?;
26         }
27         Value::Integer(Integer { n }) => {
28             match n {
29                 IntPriv::PosInt(n) => {
30                     write_uint(wr, n)?;
31                 }
32                 IntPriv::NegInt(n) => {
33                     write_sint(wr, n)?;
34                 }
35             }
36         }
37         Value::F32(val) => {
38             write_f32(wr, val)?;
39         }
40         Value::F64(val) => {
41             write_f64(wr, val)?;
42         }
43         Value::String(Utf8String { ref s }) => {
44             match *s {
45                 Ok(ref val) => write_str(wr, &val)?,
46                 Err(ref err) => write_bin(wr, &err.0)?,
47             }
48         }
49         Value::Binary(ref val) => {
50             write_bin(wr, &val)?;
51         }
52         Value::Array(ref vec) => {
53             write_array_len(wr, vec.len() as u32)?;
54             for v in vec {
55                 write_value(wr, v)?;
56             }
57         }
58         Value::Map(ref map) => {
59             write_map_len(wr, map.len() as u32)?;
60             for &(ref key, ref val) in map {
61                 write_value(wr, key)?;
62                 write_value(wr, val)?;
63             }
64         }
65         Value::Ext(ty, ref data) => {
66             write_ext_meta(wr, data.len() as u32, ty)?;
67             wr.write_all(data).map_err(Error::InvalidDataWrite)?;
68         }
69     }
70 
71     Ok(())
72 }
73