Struct serial_num::Serial
source · pub struct Serial(_);
Expand description
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.
This is an “opaque” type, similar to Instants
.
Serial numbers get their significance when being compare to one another,
but there is no method to get the “inner counter”. Another similarity
is that there is no “maximum” serial number, since every
serial number has a successor.
The window used for comparing two serial numbers is half of our number space,
(u16::MAX-1)/2 = 32767
. If two serial numbers are within that window, we simply compare
the numbers as you normally would. If we compare numbers that do not fit into
that window, like 5
and 65000
, the comparison is flipped, and we say 65000 < 5
.
This is based on the assumption that we got to 5
by increasing 65000
beyond
the point of wraparound at u16::MAX-1 = 65534
. The assumption only holds if the items you
assign serial numbers to have a short enough lifetime. The ordering of items in your state
will get messed up if there is an item that is the 32767
th successor of another item.
The final value in our number space, u16::MAX
, is reserved for the special
NAN
value. This is done to save space - you don’t need to wrap
this type in an Option
if only some items are assigned a serial number.
Implementations§
source§impl Serial
impl Serial
sourcepub const NAN: Self = _
pub const NAN: Self = _
Special value representing “no serial number”.
By convention, we say this “serial number” is less than any other. It cannot be increased, or added to.
sourcepub fn increase_get(&mut self) -> Self
pub fn increase_get(&mut self) -> Self
Increases self
with wraparound, and returns a copy.
sourcepub fn get_increase(&mut self) -> Self
pub fn get_increase(&mut self) -> Self
Returns a copy of self
, and increases self
with wraparound.
sourcepub fn dist(self, other: Self) -> u16
pub fn dist(self, other: Self) -> u16
Distance with wraparound.
For the signed difference, use Self::diff()
.
If one of the number is NAN
, the maximum distance of 32767
is returned.
If both are NAN
, we say the distance is 0
.
sourcepub fn diff(self, other: Self) -> i16
pub fn diff(self, other: Self) -> i16
Difference with wraparound.
If self < other
, the result is negative,
and if self > other
, the result is positive.
For the unsigned distance, use Self::dist()
.
If one of the number is NAN
, the maximum difference of (-)32767
is returned.
If both are NAN
, we say the difference is 0
.
Trait Implementations§
source§impl Add<u16> for Serial
impl Add<u16> for Serial
source§fn add(self, rhs: u16) -> Self::Output
fn add(self, rhs: u16) -> Self::Output
Addition with wraparound.
You can add any u16
to the serial number, but be aware that due to the wraparound
semantics, adding more than (u16::MAX-1)/2 = 32767
leads to a result that is
less than self
. Adding u16::MAX
will wraparound to the same value.
If self.is_nan()
, the returned serial number is also NAN
.
source§impl Ord for Serial
impl Ord for Serial
source§fn cmp(&self, other: &Self) -> Ordering
fn cmp(&self, other: &Self) -> Ordering
Compare with wraparound.
By convention, we say NAN
is less than any other serial number.
Based on RFC1982.
1.21.0 · source§fn max(self, other: Self) -> Selfwhere
Self: Sized,
fn max(self, other: Self) -> Selfwhere Self: Sized,
source§impl PartialEq<Serial> for Serial
impl PartialEq<Serial> for Serial
source§impl PartialOrd<Serial> for Serial
impl PartialOrd<Serial> for Serial
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
fn le(&self, other: &Rhs) -> bool
self
and other
) and is used by the <=
operator. Read more