On Wed Feb 19, 2025 at 5:51 AM JST, Timur Tabi wrote: > On Tue, 2025-02-18 at 22:16 +0900, Alexandre Courbot wrote: >> > A proper struct with `high` and `low` might be more verbose, but >> > it rules out this issue. >> >> Mmm indeed, so we would have client code looking like: >> >> let SplitU64 { high, low } = some_u64.into_u32(); >> >> instead of >> >> let (high, low) = some_u64.into_u32(); >> >> which is correct, and >> >> let (low, high) = some_u64.into_u32(); >> >> which is incorrect, but is likely to not be caught. > > I'm new to Rust, so let me see if I get this right. > > struct SplitU64 { > high: u32, > low: u32 > } > > So if you want to extract the upper 32 bits of a u64, you have to do this: > > let split = some_u64.into_u32s(); > let some_u32 = split.high; More likely this would be something like: let SplitU64 { high: some_u32, .. } = some_u64; Which is still a bit verbose, but a single-liner. Actually. How about adding methods to this trait that return either component? let some_u32 = some_u64.high_half(); let another_u32 = some_u64.low_half(); These should be used most of the times, and using destructuring/tuple would only be useful for a few select cases. > > as opposed to your original design: > > let (some_u32, _) = some_u64.into_u32s(); > > Personally, I prefer the latter. The other advantage is that into_u32s and > from_u32s are reciprocal: > > assert_eq!(u64::from_u32s(u64::into_u32s(some_u64)), some_u64); > > (or something like that) Yeah, having symmetry is definitely nice. OTOH there are no safeguards against mixing up the order and the high and low components, so a compromise will have to be made one way or the other. But if we also add the methods I proposed above, that question should matter less.