Skip to main content

prototext_core/helpers/
wire.rs

1// SPDX-FileCopyrightText: 2025 - 2026 Frederic Ruget <fred@atlant.is> <fred@s3ns.io> (GitHub: @douzebis)
2// SPDX-FileCopyrightText: 2025 - 2026 Thales Cloud Sécurisé
3//
4// SPDX-License-Identifier: MIT
5
6// ── Wire-type constants ───────────────────────────────────────────────────────
7
8pub const WT_VARINT: u32 = 0;
9pub const WT_I64: u32 = 1;
10pub const WT_LEN: u32 = 2;
11pub const WT_START_GROUP: u32 = 3;
12pub const WT_END_GROUP: u32 = 4;
13pub const WT_I32: u32 = 5;
14
15// ── Wire-encoding helpers ─────────────────────────────────────────────────────
16
17/// Append a raw varint encoding of `value` to `buf`.
18#[inline]
19pub fn write_varint(value: u64, buf: &mut Vec<u8>) {
20    let mut v = value;
21    loop {
22        let b = (v & 0x7f) as u8;
23        v >>= 7;
24        if v != 0 {
25            buf.push(b | 0x80);
26        } else {
27            buf.push(b);
28            break;
29        }
30    }
31}
32
33/// Append a field tag (wire_type 0–5) to `buf`.
34#[inline]
35pub fn write_tag(field_number: u32, wire_type: u32, buf: &mut Vec<u8>) {
36    write_varint(((field_number as u64) << 3) | (wire_type as u64), buf);
37}
38
39/// Append a VARINT field to `buf`.
40#[inline]
41pub fn write_varint_field(field_number: u32, value: u64, buf: &mut Vec<u8>) {
42    write_tag(field_number, WT_VARINT, buf);
43    write_varint(value, buf);
44}
45
46/// Append a bool field (VARINT) to `buf` — only written when `true`.
47#[inline]
48pub fn write_bool_field(field_number: u32, value: bool, buf: &mut Vec<u8>) {
49    if value {
50        write_tag(field_number, WT_VARINT, buf);
51        buf.push(1u8);
52    }
53}
54
55/// Append an optional VARINT field to `buf` — only written when `Some`.
56#[inline]
57pub fn write_opt_varint_field(field_number: u32, value: Option<u64>, buf: &mut Vec<u8>) {
58    if let Some(v) = value {
59        write_varint_field(field_number, v, buf);
60    }
61}
62
63/// Append a LEN-delimited field to `buf`.
64#[inline]
65pub fn write_len_field(field_number: u32, data: &[u8], buf: &mut Vec<u8>) {
66    write_tag(field_number, WT_LEN, buf);
67    write_varint(data.len() as u64, buf);
68    buf.extend_from_slice(data);
69}
70
71/// Append a fixed-32 field to `buf`.
72pub fn write_fixed32_field(field_number: u32, value: u32, buf: &mut Vec<u8>) {
73    write_tag(field_number, WT_I32, buf);
74    buf.extend_from_slice(&value.to_le_bytes());
75}
76
77/// Append a fixed-64 field to `buf`.
78pub fn write_fixed64_field(field_number: u32, value: u64, buf: &mut Vec<u8>) {
79    write_tag(field_number, WT_I64, buf);
80    buf.extend_from_slice(&value.to_le_bytes());
81}