msgpack/pack/
value.rs

1use super::primitive::write_all;
2use super::{
3    pack_ary_header, pack_bin, pack_bool, pack_ext_header, pack_f32, pack_f64, pack_from_i64,
4    pack_from_u64, pack_map_header, pack_nil, pack_str, pack_str_from_slice, pack_timestamp,
5};
6use crate::pack_error::PackError;
7
8use crate::value;
9use crate::value::float::{self, Float};
10use crate::value::integer::{self, Integer};
11use crate::value::Value;
12use std::io;
13
14pub fn pack_value<W: io::Write>(writer: &mut W, val: Value) -> Result<(), PackError> {
15    match val {
16        Value::Integer(Integer { n }) => match n {
17            integer::Number::PosInt(v) => pack_from_u64(writer, v),
18            integer::Number::NegInt(v) => pack_from_i64(writer, v),
19        },
20        Value::Nil => pack_nil(writer),
21        Value::Boolean(v) => pack_bool(writer, v),
22        Value::Float(Float { n }) => match n {
23            float::Number::Float32(v) => pack_f32(writer, v),
24            float::Number::Float64(v) => pack_f64(writer, v),
25        },
26        Value::Binary(v) => pack_bin(writer, &v),
27        Value::String(value::Utf8String { ref s }) => {
28            match *s {
29                Ok(ref s) => pack_str(writer, &s.as_str()),
30                Err((ref s, _)) => pack_str_from_slice(writer, s),
31            }
32        }
33        Value::Array(vs) => {
34            pack_ary_header(writer, vs.len())?;
35            for v in vs {
36                pack_value(writer, v)?;
37            }
38            Ok(())
39        }
40        Value::Map(vs) => {
41            pack_map_header(writer, vs.len())?;
42            for (k, v) in vs {
43                pack_value(writer, k)?;
44                pack_value(writer, v)?;
45            }
46            Ok(())
47        }
48        Value::Extension(tag, v) => {
49            pack_ext_header(writer, tag, v.len())?;
50            write_all(writer, &v)
51        }
52        Value::Timestamp(sec, nsec) => pack_timestamp(writer, sec, nsec),
53    }
54}