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}