pub(super) struct Repr {
ptr: *const u8,
}
Expand description
The internal representation of a TimeZone
.
It has 6 different possible variants: UTC
, Etc/Unknown
, fixed
offset, static
TZif, Arc
TZif or Arc
POSIX time zone.
This design uses pointer tagging so that:
- The size of a
TimeZone
stays no bigger than a single word. - In core-only environments, a
TimeZone
can be created from compile-time TZif data without allocating. - UTC, unknown and fixed offset time zone does not require allocating.
- We can still alloc for TZif and POSIX time zones created at runtime.
(Allocating for TZif at runtime is the intended common case, and
corresponds to reading
/usr/share/zoneinfo
entries.)
We achieve this through pointer tagging and careful use of a strict provenance polyfill (because of MSRV). We use the lower 4 bits of a pointer to indicate which variant we have. This is sound because we require all types that we allocate for to have a minimum alignment of 8 bytes.
Fields§
§ptr: *const u8
Implementations§
Source§impl Repr
impl Repr
const BITS: usize = 7usize
pub(super) const UTC: usize = 1usize
pub(super) const UNKNOWN: usize = 2usize
pub(super) const FIXED: usize = 3usize
pub(super) const STATIC_TZIF: usize = 0usize
pub(super) const ARC_TZIF: usize = 4usize
pub(super) const ARC_POSIX: usize = 5usize
const ALIGN: usize = 8usize
Sourcepub(super) const fn fixed(offset: Offset) -> Repr
pub(super) const fn fixed(offset: Offset) -> Repr
Creates a representation for a fixed offset time zone.
Sourcepub(super) const fn static_tzif(
tzif: &'static Tzif<&'static str, &'static str, &'static [TzifLocalTimeType], &'static [i64], &'static [TzifDateTime], &'static [TzifDateTime], &'static [TzifTransitionInfo]>,
) -> Repr
pub(super) const fn static_tzif( tzif: &'static Tzif<&'static str, &'static str, &'static [TzifLocalTimeType], &'static [i64], &'static [TzifDateTime], &'static [TzifDateTime], &'static [TzifTransitionInfo]>, ) -> Repr
Creates a representation for a created-at-compile-time TZif time zone.
This can only be correctly called by the jiff-static
proc macro.
Sourcepub(super) fn arc_tzif(
tzif: Arc<Tzif<String, ArrayStr<ABBREVIATION_MAX>, Vec<TzifLocalTimeType>, Vec<i64>, Vec<TzifDateTime>, Vec<TzifDateTime>, Vec<TzifTransitionInfo>>>,
) -> Repr
pub(super) fn arc_tzif( tzif: Arc<Tzif<String, ArrayStr<ABBREVIATION_MAX>, Vec<TzifLocalTimeType>, Vec<i64>, Vec<TzifDateTime>, Vec<TzifDateTime>, Vec<TzifTransitionInfo>>>, ) -> Repr
Creates a representation for a TZif time zone.
Sourcepub(super) fn arc_posix(
posix_tz: Arc<PosixTimeZone<ArrayStr<ABBREVIATION_MAX>>>,
) -> Repr
pub(super) fn arc_posix( posix_tz: Arc<PosixTimeZone<ArrayStr<ABBREVIATION_MAX>>>, ) -> Repr
Creates a representation for a POSIX time zone.
Sourcepub(super) fn is_unknown(&self) -> bool
pub(super) fn is_unknown(&self) -> bool
Returns true if and only if this representation corresponds to the
Etc/Unknown
time zone.
Sourcepub(super) unsafe fn get_static_tzif(
&self,
) -> &'static Tzif<&'static str, &'static str, &'static [TzifLocalTimeType], &'static [i64], &'static [TzifDateTime], &'static [TzifDateTime], &'static [TzifTransitionInfo]>
pub(super) unsafe fn get_static_tzif( &self, ) -> &'static Tzif<&'static str, &'static str, &'static [TzifLocalTimeType], &'static [i64], &'static [TzifDateTime], &'static [TzifDateTime], &'static [TzifTransitionInfo]>
Gets the static TZif representation.
§Safety
Callers must ensure that the pointer tag is STATIC_TZIF
.
Sourcepub(super) unsafe fn get_arc_tzif<'a>(
&'a self,
) -> &'a Tzif<String, ArrayStr<ABBREVIATION_MAX>, Vec<TzifLocalTimeType>, Vec<i64>, Vec<TzifDateTime>, Vec<TzifDateTime>, Vec<TzifTransitionInfo>>
pub(super) unsafe fn get_arc_tzif<'a>( &'a self, ) -> &'a Tzif<String, ArrayStr<ABBREVIATION_MAX>, Vec<TzifLocalTimeType>, Vec<i64>, Vec<TzifDateTime>, Vec<TzifDateTime>, Vec<TzifTransitionInfo>>
Sourcepub(super) unsafe fn get_arc_posix<'a>(
&'a self,
) -> &'a PosixTimeZone<ArrayStr<ABBREVIATION_MAX>>
pub(super) unsafe fn get_arc_posix<'a>( &'a self, ) -> &'a PosixTimeZone<ArrayStr<ABBREVIATION_MAX>>
Gets the Arc
POSIX time zone representation.
§Safety
Callers must ensure that the pointer tag is ARC_POSIX
.
Sourcepub(super) fn tag(&self) -> usize
pub(super) fn tag(&self) -> usize
Returns the tag on the representation’s pointer.
The value is guaranteed to be one of the constant tag values.
Sourcepub(super) const unsafe fn copy(&self) -> Repr
pub(super) const unsafe fn copy(&self) -> Repr
Returns a dumb copy of this representation.
§Safety
Callers must ensure that this representation’s tag is UTC, UNKNOWN, FIXED or STATIC_TZIF.
Namely, this specifically does not increment the ref count for
the Arc
pointers when the tag is ARC_TZIF
or ARC_POSIX
.
This means that incorrect usage of this routine can lead to
use-after-free.
NOTE: It would be nice if we could make this copy
routine safe,
or at least panic if it’s misused. But to do that, you need to know
the time zone variant. And to know the time zone variant, you need
to “look” at the tag in the pointer. And looking at the address of
a pointer in a const
context is precarious.