rmp/encode/
uint.rs

1use super::{write_marker, RmpWrite};
2use crate::encode::ValueWriteError;
3use crate::Marker;
4
5/// Encodes and attempts to write an unsigned small integer value as a positive fixint into the
6/// given write.
7///
8/// According to the MessagePack specification, a positive fixed integer value is represented using
9/// a single byte in `[0x00; 0x7f]` range inclusively, prepended with a special marker mask.
10///
11/// The function is **strict** with the input arguments - it is the user's responsibility to check
12/// if the value fits in the described range, otherwise it will panic.
13///
14/// If you are not sure if the value fits in the given range use `write_uint` instead, which
15/// automatically selects the most compact integer representation.
16///
17/// # Errors
18///
19/// This function will return `FixedValueWriteError` on any I/O error occurred while writing the
20/// positive integer marker.
21///
22/// # Panics
23///
24/// Panics if `val` is greater than 127.
25#[inline]
26pub fn write_pfix<W: RmpWrite>(wr: &mut W, val: u8) -> Result<(), W::Error> {
27    assert!(val < 128);
28    write_marker(wr, Marker::FixPos(val)).map_err(|e| e.0)?;
29    Ok(())
30}
31
32/// Encodes and attempts to write an `u8` value as a 2-byte sequence into the given write.
33///
34/// The first byte becomes the marker and the second one will represent the data itself.
35///
36/// Note, that this function will encode the given value in 2-byte sequence no matter what, even if
37/// the value can be represented using single byte as a positive fixnum.
38///
39/// If you need to fit the given buffer efficiently use `write_uint` instead, which automatically
40/// selects the appropriate integer representation.
41///
42/// # Errors
43///
44/// This function will return `ValueWriteError` on any I/O error occurred while writing either the
45/// marker or the data.
46///
47/// # Examples
48/// ```
49/// let mut buf = [0x00, 0x00];
50///
51/// rmp::encode::write_u8(&mut &mut buf[..], 146).ok().unwrap();
52/// assert_eq!([0xcc, 0x92], buf);
53///
54/// // Note, that 42 can be represented simply as `[0x2a]`, but the function emits 2-byte sequence.
55/// rmp::encode::write_u8(&mut &mut buf[..], 42).ok().unwrap();
56/// assert_eq!([0xcc, 0x2a], buf);
57/// ```
58pub fn write_u8<W: RmpWrite>(wr: &mut W, val: u8) -> Result<(), ValueWriteError<W::Error>> {
59    write_marker(wr, Marker::U8)?;
60    wr.write_data_u8(val)?;
61    Ok(())
62}
63
64/// Encodes and attempts to write an `u16` value strictly as a 3-byte sequence into the given write.
65///
66/// The first byte becomes the marker and the others will represent the data itself.
67///
68/// Note, that this function will encode the given value in 3-byte sequence no matter what, even if
69/// the value can be represented using single byte as a positive fixnum.
70///
71/// If you need to fit the given buffer efficiently use `write_uint` instead, which automatically
72/// selects the appropriate integer representation.
73///
74/// # Errors
75///
76/// This function will return `ValueWriteError` on any I/O error occurred while writing either the
77/// marker or the data.
78pub fn write_u16<W: RmpWrite>(wr: &mut W, val: u16) -> Result<(), ValueWriteError<W::Error>> {
79    write_marker(wr, Marker::U16)?;
80    wr.write_data_u16(val)?;
81    Ok(())
82}
83
84/// Encodes and attempts to write an `u32` value strictly as a 5-byte sequence into the given write.
85///
86/// The first byte becomes the marker and the others will represent the data itself.
87///
88/// Note, that this function will encode the given value in 5-byte sequence no matter what, even if
89/// the value can be represented using single byte as a positive fixnum.
90///
91/// If you need to fit the given buffer efficiently use `write_uint` instead, which automatically
92/// selects the appropriate integer representation.
93///
94/// # Errors
95///
96/// This function will return `ValueWriteError` on any I/O error occurred while writing either the
97/// marker or the data.
98pub fn write_u32<W: RmpWrite>(wr: &mut W, val: u32) -> Result<(), ValueWriteError<W::Error>> {
99    write_marker(wr, Marker::U32)?;
100    wr.write_data_u32(val)?;
101    Ok(())
102}
103
104/// Encodes and attempts to write an `u64` value strictly as a 9-byte sequence into the given write.
105///
106/// The first byte becomes the marker and the others will represent the data itself.
107///
108/// Note, that this function will encode the given value in 9-byte sequence no matter what, even if
109/// the value can be represented using single byte as a positive fixnum.
110///
111/// If you need to fit the given buffer efficiently use `write_uint` instead, which automatically
112/// selects the appropriate integer representation.
113///
114/// # Errors
115///
116/// This function will return `ValueWriteError` on any I/O error occurred while writing either the
117/// marker or the data.
118pub fn write_u64<W: RmpWrite>(wr: &mut W, val: u64) -> Result<(), ValueWriteError<W::Error>> {
119    write_marker(wr, Marker::U64)?;
120    wr.write_data_u64(val)?;
121    Ok(())
122}
123
124/// Encodes and attempts to write an `u8` value into the given write using the most efficient
125/// representation, returning the marker used.
126///
127/// See [`write_uint`] for more info.
128pub fn write_uint8<W: RmpWrite>(wr: &mut W, val: u8) -> Result<Marker, ValueWriteError<W::Error>> {
129    if val < 128 {
130        write_pfix(wr, val)
131            .and(Ok(Marker::FixPos(val)))
132            .map_err(ValueWriteError::InvalidMarkerWrite)
133    } else {
134        write_u8(wr, val).and(Ok(Marker::U8))
135    }
136}
137
138/// Encodes and attempts to write an `u64` value into the given write using the most efficient
139/// representation, returning the marker used.
140///
141/// This function obeys the MessagePack specification, which requires that the serializer SHOULD use
142/// the format which represents the data in the smallest number of bytes.
143///
144/// The first byte becomes the marker and the others (if present, up to 9) will represent the data
145/// itself.
146///
147/// # Errors
148///
149/// This function will return `ValueWriteError` on any I/O error occurred while writing either the
150/// marker or the data.
151pub fn write_uint<W: RmpWrite>(wr: &mut W, val: u64) -> Result<Marker, ValueWriteError<W::Error>> {
152    if val < 256 {
153        write_uint8(wr, val as u8)
154    } else if val < 65536 {
155        write_u16(wr, val as u16).and(Ok(Marker::U16))
156    } else if val < 4294967296 {
157        write_u32(wr, val as u32).and(Ok(Marker::U32))
158    } else {
159        write_u64(wr, val).and(Ok(Marker::U64))
160    }
161}