1use super::{Header, Tag, WireType};
4use crate::message::Message;
5
6pub fn uint64(tag: Tag, value: u64) -> usize {
8 header(tag, WireType::UInt64) + vint64::encoded_len(value)
9}
10
11pub fn sint64(tag: Tag, value: i64) -> usize {
13 header(tag, WireType::SInt64) + vint64::signed::encoded_len(value)
14}
15
16pub fn bytes(tag: Tag, bytes: &[u8]) -> usize {
18 dynamically_sized(tag, WireType::Bytes, bytes.len())
19}
20
21pub fn string(tag: Tag, string: &str) -> usize {
23 dynamically_sized(tag, WireType::String, string.len())
24}
25
26pub fn message(tag: Tag, message: &dyn Message) -> usize {
28 dynamically_sized(tag, WireType::Message, message.encoded_len())
29}
30
31pub fn message_seq<'a>(tag: Tag, messages: impl Iterator<Item = &'a dyn Message>) -> usize {
33 let body_len: usize = messages
34 .map(|msg| {
35 let encoded_len = msg.encoded_len();
36 vint64::encoded_len(encoded_len as u64) + encoded_len
37 })
38 .sum();
39
40 header(tag, WireType::Sequence)
41 + vint64::encoded_len((body_len as u64) << 4 | WireType::Message as u64)
42 + body_len
43}
44
45fn header(tag: Tag, wire_type: WireType) -> usize {
47 Header::new(tag, false, wire_type).encoded_len()
49}
50
51fn dynamically_sized(tag: Tag, wire_type: WireType, length: usize) -> usize {
53 header(tag, wire_type) + vint64::encoded_len(length as u64) + length
54}
55
56#[cfg(test)]
57mod tests {
58 use super::*;
59
60 #[test]
61 fn uint64_length() {
62 assert_eq!(uint64(1, 42), 2);
63 }
64
65 #[test]
66 fn sint64_length() {
67 assert_eq!(sint64(2, -42), 2);
68 }
69
70 #[test]
71 fn bytes_length() {
72 assert_eq!(bytes(3, b"foobar"), 8)
73 }
74
75 #[test]
76 fn string_length() {
77 assert_eq!(string(4, "baz"), 5);
78 }
79}