Skip to main content

prototext_core/helpers/
codecs.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// ── Numeric type codecs ───────────────────────────────────────────────────────
7// Mirror prototext/helpers.py exactly.  All functions are trivial but must
8// be correct — errors here silently break round-trip fidelity.
9
10/// Decode varint as int64 (two's complement).
11#[inline]
12pub fn decode_int64(v: u64) -> i64 {
13    v as i64
14}
15
16/// Decode varint as int32 (two's complement, low 32 bits).
17#[inline]
18pub fn decode_int32(v: u64) -> i32 {
19    (v as u32) as i32
20}
21
22/// Decode varint as uint32.
23#[inline]
24pub fn decode_uint32(v: u64) -> u32 {
25    v as u32
26}
27
28/// Decode varint as uint64.
29#[inline]
30pub fn decode_uint64(v: u64) -> u64 {
31    v
32}
33
34/// Decode varint as bool (0 → false, 1 → true).
35#[inline]
36pub fn decode_bool(v: u64) -> bool {
37    v != 0
38}
39
40/// Decode varint as sint32 (zig-zag).
41#[inline]
42pub fn decode_sint32(v: u64) -> i32 {
43    let n = v as u32;
44    ((n >> 1) as i32) ^ -((n & 1) as i32)
45}
46
47/// Decode varint as sint64 (zig-zag).
48#[inline]
49pub fn decode_sint64(v: u64) -> i64 {
50    ((v >> 1) as i64) ^ -((v & 1) as i64)
51}
52
53/// Decode 4 little-endian bytes as fixed32 (uint32).
54#[inline]
55pub fn decode_fixed32(data: &[u8]) -> u32 {
56    u32::from_le_bytes(data[..4].try_into().unwrap())
57}
58
59/// Decode 4 little-endian bytes as sfixed32 (int32).
60#[inline]
61pub fn decode_sfixed32(data: &[u8]) -> i32 {
62    i32::from_le_bytes(data[..4].try_into().unwrap())
63}
64
65/// Decode 4 little-endian bytes as f32.
66#[inline]
67pub fn decode_float(data: &[u8]) -> f32 {
68    f32::from_le_bytes(data[..4].try_into().unwrap())
69}
70
71/// Decode 8 little-endian bytes as fixed64 (uint64).
72#[inline]
73pub fn decode_fixed64(data: &[u8]) -> u64 {
74    u64::from_le_bytes(data[..8].try_into().unwrap())
75}
76
77/// Decode 8 little-endian bytes as sfixed64 (int64).
78#[inline]
79pub fn decode_sfixed64(data: &[u8]) -> i64 {
80    i64::from_le_bytes(data[..8].try_into().unwrap())
81}
82
83/// Decode 8 little-endian bytes as f64.
84#[inline]
85pub fn decode_double(data: &[u8]) -> f64 {
86    f64::from_le_bytes(data[..8].try_into().unwrap())
87}