Question Details

No question body available.

Tags

rust serde

Answers (1)

Accepted Answer Available
Accepted Answer
October 4, 2025 Score: 24 Rep: 30,014 Quality: Expert Completeness: 80%

Serde unconditionally casts an usize/isize to u64/i64 before serializing:

primitiveimpl!(isize, serializei64 as i64);
// …
primitiveimpl!(usize, serializeu64 as u64);

and when deserializing depending on the type visited (defaulting to u64 for non self describing formats) it uses an as-cast or TryFrom:

impldeserializenum! {
    usize, NonZeroUsize, deserializeu64
    numasself!(u8:visitu8 u16:visitu16);
    inttouint!(i8:visiti8 i16:visiti16 i32:visiti32 i64:visiti64);
    uinttoself!(u32:visitu32 u64:visitu64);
}

Where numasself uses an as-cast, inttouint checks for >= 0 and uses TryFrom and uintto_self uses TryFrom

That means a bare usize causes an Err to be returned when it's deserialized from a value that's bigger than usize::MAX.

To achieve saturating semantics you can wrap your usize in Saturating.


Would casting usize to u64 be overly defensive?

For serializing yes, it would be. serde already does that.

For deserializing, it would allow any value up to u64::MAX on all platforms instead of just usize::MAX.