This crate offers a two-byte serial number with wraparound.
A serial number is an identifier assigned incrementally to an item.
In many cases, you can use a u32
or u64
and call it
a day, without having to worry about overflow. The niche benefit of this type
is that it only uses the space of a u16
, with the problem of overflow solved
by wraparound.
[]
= "0.2"
# or with addtional features:
[]
= { = "0.2", = ["serde"] }
The following feature flags are available:
bincode
: Implements bincode'sDecode/Encode
for theSerial
typeserde
: Implements serde'sDeserialize/Serialize
for theSerial
type
The Minimum Supported Rust Version (MSRV) for this crate is 1.60.0
.
Usage
Simple example
use Serial;
// the default is a reference point - not serial number "zero"
let mut a = default;
let mut b = default;
let mut c = default;
// three ways to increase
let x = a.increase_get; // increase, then copy
let y = b.get_increase; // copy, then increase
c.increase;
assert!;
assert_eq!; // "diff()" is signed
assert_eq!; // "dist()" is unsigned
// addition is the same as calling "increase()" n times
assert_eq!;
Wraparound example
use Serial;
// a serial number can be increased indefinitely
let mut x = default;
for _ in 0..u16MAX
let x = x + u16MAX + u16MAX + u16MAX;
// comparison is trivial as long as two serial numbers have
// a distance of less than half of our number space (32767).
let a = default + 5;
let b = default + 32000;
assert!; // 5th successor < 32000th successor
// but: the comparison flips if the distance is larger
let a = default + 5;
let b = default + 65000;
assert!; // 5th successor > 65000th successor
// this means that you get the right ordering as long as
// you compare one serial number at most with one that
// is its 32767th successor.
// a real use case of this is to sign UDP packets with
// a serial number. this would allow you to restore the
// order of packets at the receiver as long as you never
// look at more than the 32767 last packets (which
// should be much more than you need).
The NAN
value
use Serial;
// "NAN" exists to have value representing "no serial number",
// since it saves encoding space vs wrapping Serial in an Option.
let nan = NAN;
let default = default;
// you can check whether a serial number is NAN
assert!;
// NAN cannot be increased
assert_eq!;
// distance between two NAN values is zero
assert_eq!;
assert_eq!;
// distance and difference of non-NAN to NAN is the maximum distance
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
// partial ordering does not include the NAN value
assert_eq!;
assert!;
Changelog
0.2.0 - 2023-04-27
- Improved documentation
- Set MSRV to
1.60.0
- Up
bincode
to^2.0.0-rc.3
0.1.1 - 2023-01-06
- Disabled the
std
features of bincode/serde to enableno_std
support.