///|
/// QUIC ACK generation (RFC 9000 §13.2, §19.3): an `AckRangeSet` records
/// received packet numbers with gaps, produces the Largest / First Range /
/// (Gap, Length) fields, and reconstructs the ranges. A `PacketNumberSpace`
/// then owes an ACK after ack-eliciting packets and clears it once built.
///
/// moon run src/examples/22-quic-ack --target native
#coverage.skip
fn main {
run() catch {
e => println("ack error: \{e}")
}
}
///|
fn run() -> Unit raise {
let set = @frame.Seen::new()
for pn in [0UL, 1UL, 2UL, 4UL, 5UL, 7UL] {
set.add(pn)
}
println(
"largest=\{opt_u(set.largest())} contains(3)=\{set.contains(3UL)} contains(5)=\{set.contains(5UL)}",
)
match set.fields() {
Some((largest, first_range, pairs)) => {
println(
"ack fields: largest=\{largest.to_string()} first_range=\{first_range.to_string()} gap/len pairs=\{pairs.length()}",
)
let ranges = @frame.Seen::read(largest, first_range, pairs)
println(
"reconstructed ranges = \{ranges.ranges().length()} (expect 3: 0-2, 4-5, 7-7)",
)
}
None => println("empty set")
}
let s = @packet.Space::new()
s.on_packet_received(0L, true)
s.on_packet_received(1L, true)
s.on_packet_received(3L, true)
println("ack pending = \{s.ack_pending()}")
match s.build_ack(0UL) {
Some(frame) => {
println("built ACK, ack_pending now = \{s.ack_pending()}")
println("acked ranges from frame = \{frame.acked().length()}")
}
None => println("no ack owed")
}
}
///|
fn opt_u(o : UInt64?) -> String {
match o {
Some(n) => n.to_string()
None => "(none)"
}
}