1mod int;
2mod primitive;
3mod timestamp;
4mod uint;
5mod value;
6
7use crate::{code, PackError};
8use primitive::*;
9use std::io;
10
11pub use int::*;
12pub use primitive::write_all;
13pub use timestamp::*;
14pub use uint::*;
15pub use value::pack_value;
16
17pub fn pack_f32<W: io::Write>(writer: &mut W, v: f32) -> Result<(), PackError> {
18 write_data_u8(writer, code::FLOAT32)?;
19 write_data_f32(writer, v)
20}
21
22pub fn pack_f64<W: io::Write>(writer: &mut W, v: f64) -> Result<(), PackError> {
23 write_data_u8(writer, code::FLOAT64)?;
24 write_data_f64(writer, v)
25}
26
27pub fn pack_bool<W: io::Write>(writer: &mut W, v: bool) -> Result<(), PackError> {
28 write_data_u8(writer, if v { code::TRUE } else { code::FALSE })
29}
30
31pub fn pack_nil<W: io::Write>(writer: &mut W) -> Result<(), PackError> {
32 write_data_u8(writer, code::NIL)
33}
34
35const FIXSTR_LIMIT: usize = 1 << 5;
36const STR8_LIMIT: usize = 1 << 8;
37const STR16_LIMIT: usize = 1 << 16;
38const STR32_LIMIT: usize = 1 << 32;
39
40pub fn pack_str<W: io::Write>(writer: &mut W, v: &str) -> Result<(), PackError> {
41 let len = v.len();
42 if len < FIXSTR_LIMIT {
43 write_data_u8(writer, code::FIX_STR | len as u8)?;
44 write_all(writer, v[..len].as_bytes())
45 } else if len < STR8_LIMIT {
46 write_data_u8(writer, code::STR8)?;
47 write_data_u8(writer, len as u8)?;
48 write_all(writer, v[..len].as_bytes())
49 } else if len < STR16_LIMIT {
50 write_data_u8(writer, code::STR16)?;
51 write_data_u16(writer, len as u16)?;
52 write_all(writer, v[..len].as_bytes())
53 } else if len < STR32_LIMIT {
54 write_data_u8(writer, code::STR32)?;
55 write_data_u32(writer, len as u32)?;
56 write_all(writer, v[..len].as_bytes())
57 } else {
58 unreachable!()
59 }
60}
61
62pub fn pack_str_from_slice<W: io::Write>(writer: &mut W, v: &[u8]) -> Result<(), PackError> {
64 let len = v.len();
65 if len < FIXSTR_LIMIT {
66 write_data_u8(writer, code::FIX_STR | len as u8)?;
67 write_all(writer, &v[..len])
68 } else if len < STR8_LIMIT {
69 write_data_u8(writer, code::STR8)?;
70 write_data_u8(writer, len as u8)?;
71 write_all(writer, &v[..len])
72 } else if len < STR16_LIMIT {
73 write_data_u8(writer, code::STR16)?;
74 write_data_u16(writer, len as u16)?;
75 write_all(writer, &v[..len])
76 } else if len < STR32_LIMIT {
77 write_data_u8(writer, code::STR32)?;
78 write_data_u32(writer, len as u32)?;
79 write_all(writer, &v[..len])
80 } else {
81 unreachable!()
82 }
83}
84
85const BIN8_LIMIT: usize = 1 << 8;
86const BIN16_LIMIT: usize = 1 << 16;
87const BIN32_LIMIT: usize = 1 << 32;
88
89pub fn pack_bin<W: io::Write>(writer: &mut W, v: &[u8]) -> Result<(), PackError> {
90 let len = v.len();
91 if len < BIN8_LIMIT {
92 write_data_u8(writer, code::BIN8)?;
93 write_data_u8(writer, len as u8)?;
94 write_all(writer, &v[..len])
95 } else if len < BIN16_LIMIT {
96 write_data_u8(writer, code::BIN16)?;
97 write_data_u16(writer, len as u16)?;
98 write_all(writer, &v[..len])
99 } else if len < BIN32_LIMIT {
100 write_data_u8(writer, code::BIN32)?;
101 write_data_u32(writer, len as u32)?;
102 write_all(writer, &v[..len])
103 } else {
104 unreachable!()
105 }
106}
107
108const FIXARRAY_LIMIT: usize = 1 << 4;
109const ARRAY16_LIMIT: usize = 1 << 16;
110const ARRAY32_LIMIT: usize = 1 << 32;
111
112pub fn pack_ary_header<W: io::Write>(writer: &mut W, len: usize) -> Result<(), PackError> {
113 if len < FIXARRAY_LIMIT {
114 write_data_u8(writer, code::FIX_ARRAY | (len as u8))
115 } else if len < ARRAY16_LIMIT {
116 write_data_u8(writer, code::ARRAY16)?;
117 write_data_u16(writer, len as u16)
118 } else if len < ARRAY32_LIMIT {
119 write_data_u8(writer, code::ARRAY32)?;
120 write_data_u32(writer, len as u32)
121 } else {
122 unreachable!()
123 }
124}
125
126const FIXMAP_LIMIT: usize = 1 << 4;
127const MAP16_LIMIT: usize = 1 << 16;
128const MAP32_LIMIT: usize = 1 << 32;
129
130pub fn pack_map_header<W: io::Write>(writer: &mut W, len: usize) -> Result<(), PackError> {
131 if len < FIXMAP_LIMIT {
132 write_data_u8(writer, code::FIX_MAP | (len as u8))
133 } else if len < MAP16_LIMIT {
134 write_data_u8(writer, code::MAP16)?;
135 write_data_u16(writer, len as u16)
136 } else if len < MAP32_LIMIT {
137 write_data_u8(writer, code::MAP32)?;
138 write_data_u32(writer, len as u32)
139 } else {
140 unreachable!()
141 }
142}
143
144pub fn pack_ext_header<W: io::Write>(
145 writer: &mut W,
146 ext_type: i8,
147 len: usize,
148) -> Result<(), PackError> {
149 use std::io::ErrorKind;
150 if ext_type < 0 {
151 return Err(PackError::WriteError(io::Error::new(
152 ErrorKind::Other,
153 "type < 0 is reserved for future extension",
154 )));
155 }
156 match len {
157 1 => write_data_u8(writer, code::FIXEXT1)?,
158 2 => write_data_u8(writer, code::FIXEXT2)?,
159 4 => write_data_u8(writer, code::FIXEXT4)?,
160 8 => write_data_u8(writer, code::FIXEXT8)?,
161 16 => write_data_u8(writer, code::FIXEXT16)?,
162 17..=256 => {
163 write_data_u8(writer, code::EXT8)?;
164 write_data_u8(writer, len as u8)?
165 }
166 256..=65536 => {
167 write_data_u8(writer, code::EXT16)?;
168 write_data_u16(writer, len as u16)?
169 }
170 _ => {
171 write_data_u8(writer, code::EXT32)?;
172 write_data_u32(writer, len as u32)?
173 }
174 };
175
176 write_data_i8(writer, ext_type)
177}