1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
use bun_core::String;
use super::super::types::int_types::Int4;
use super::new_reader::NewReader;
#[derive(Default)]
pub struct NegotiateProtocolVersion {
pub version: Int4,
pub unrecognized_options: Vec<String>,
}
impl NegotiateProtocolVersion {
// PORT NOTE: reshaped from out-param `fn(this: *@This(), ...) !void` to `-> Result<Self, E>`.
// TODO(port): narrow error set
pub fn decode_internal<Container: super::new_reader::ReaderContext>(
mut reader: NewReader<Container>,
) -> Result<Self, bun_core::Error> {
let length = reader.length()?;
debug_assert!(length >= 4);
let version = reader.int4()?;
let mut this = Self {
version,
unrecognized_options: Vec::new(),
};
let unrecognized_options_count: u32 = reader.int4()?;
this.unrecognized_options.reserve(
(unrecognized_options_count as usize).saturating_sub(this.unrecognized_options.len()),
);
// errdefer { for ... option.deinit(); list.deinit(allocator) } — deleted:
// Vec<bun_core::String> drops each element on the `?` error path automatically.
for _ in 0..unrecognized_options_count {
let option = reader.read_z()?;
if option.slice().len() == 0 {
break;
}
// `defer option.deinit()` — deleted; `option` drops at end of iteration.
// TODO(port): Zig used `borrowUTF8` then dropped `option`; that would dangle.
// Clone instead — `option` is Temporary into the connection buffer either way.
this.unrecognized_options
.push(String::clone_utf8(option.slice()));
// PERF(port): was appendAssumeCapacity — profile if it shows up on a hot path.
}
Ok(this)
}
}
// ported from: src/sql/postgres/protocol/NegotiateProtocolVersion.zig