1
1
mirror of https://github.com/Byron/gitoxide synced 2025-10-06 11:02:39 +02:00

feat: Add size_ok for asserting size is not too big

This compares using `==` on 64-bit targets and `<=` on 32-bit
targets.

As noted in the documentation comment, when assertions about data
stuructures' sizes are being done to safeguard against them growing
too big, then it may be acceptable to use `<=` if the structure is
smaller on 32-bit targets, but it is still valuable to be able to
use `==` on 64-bit targets in the same assertions, since this
guards against a data structure becoming smaller, other changes
causing the smaller size to be important for memory usage or speed,
but then the data structure growing again, up to its original size.
An unconditional `<=` will not catch this, while `size_ok` usually
will.

A related reason to do a `==` on 64-bit systems is so that the
expected value being compared to remains tied to the code. It can
otherwise become unclear what the expected value's significance is
and whether it ought to be updated.
This commit is contained in:
Eliah Kagan
2024-11-17 20:18:28 -05:00
parent 178cf25664
commit 77c3c59d1f

View File

@@ -882,6 +882,30 @@ impl Drop for Env<'_> {
}
}
/// Check data structure size, comparing strictly on 64-bit targets.
///
/// - On 32-bit targets, checks if `actual_size` is at most `expected_64_bit_size`.
/// - On 64-bit targets, checks if `actual_size` is exactly `expected_64_bit_size`.
///
/// This is for assertions about the size of data structures, when the goal is to keep them from
/// growing too large even across breaking changes. Such assertions must always fail when data
/// structures grow larger than they have ever been, for which `<=` is enough. But it also helps to
/// know when they have shrunk unexpectedly. They may shrink, other changes may rely on the smaller
/// size for acceptable performance, and then they may grow again to their earlier size.
///
/// The problem with `==` is that data structures are often smaller on 32-bit targets. This could
/// be addressed by asserting separate exact 64-bit and 32-bit sizes. But sizes may also differ
/// across 32-bit targets, due to ABI and layout/packing details. That can happen across 64-bit
/// targets too, but it seems less common.
///
/// For those reasons, this function does a `==` on 64-bit targets, but a `<=` on 32-bit targets.
pub fn size_ok(actual_size: usize, expected_64_bit_size: usize) -> bool {
#[cfg(target_pointer_width = "64")]
return actual_size == expected_64_bit_size;
#[cfg(target_pointer_width = "32")]
return actual_size <= expected_64_bit_size;
}
#[cfg(test)]
mod tests {
use super::*;