Skip to content

Commit e91d5a9

Browse files
authored
Add smart pointer implementations for TimeZone traits (#614)
Adds some missing trait implementations for Timezone related traits on smart pointers, making it much more convenient to pass a `Rc<impl TimeZoneProvider>` as an `impl TimeZoneProvider`.
1 parent 02b37c7 commit e91d5a9

File tree

1 file changed

+137
-0
lines changed

1 file changed

+137
-0
lines changed

provider/src/provider.rs

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,65 @@ pub trait TimeZoneProvider {
211211
) -> TimeZoneProviderResult<Option<EpochNanoseconds>>;
212212
}
213213

214+
macro_rules! provider_deref_impl {
215+
($target:ty) => {
216+
impl<P> TimeZoneProvider for $target
217+
where
218+
P: TimeZoneProvider + ?Sized,
219+
{
220+
#[inline]
221+
fn get(&self, ident: &[u8]) -> TimeZoneProviderResult<TimeZoneId> {
222+
(**self).get(ident)
223+
}
224+
225+
#[inline]
226+
fn identifier(&self, id: TimeZoneId) -> TimeZoneProviderResult<Cow<'_, str>> {
227+
(**self).identifier(id)
228+
}
229+
230+
#[inline]
231+
fn canonicalized(&self, id: TimeZoneId) -> TimeZoneProviderResult<TimeZoneId> {
232+
(**self).canonicalized(id)
233+
}
234+
235+
#[inline]
236+
fn candidate_nanoseconds_for_local_epoch_nanoseconds(
237+
&self,
238+
id: TimeZoneId,
239+
local_datetime: IsoDateTime,
240+
) -> TimeZoneProviderResult<CandidateEpochNanoseconds> {
241+
(**self).candidate_nanoseconds_for_local_epoch_nanoseconds(id, local_datetime)
242+
}
243+
244+
#[inline]
245+
fn transition_nanoseconds_for_utc_epoch_nanoseconds(
246+
&self,
247+
id: TimeZoneId,
248+
epoch_nanoseconds: i128,
249+
) -> TimeZoneProviderResult<UtcOffsetSeconds> {
250+
(**self).transition_nanoseconds_for_utc_epoch_nanoseconds(id, epoch_nanoseconds)
251+
}
252+
253+
#[inline]
254+
fn get_time_zone_transition(
255+
&self,
256+
id: TimeZoneId,
257+
epoch_nanoseconds: i128,
258+
direction: TransitionDirection,
259+
) -> TimeZoneProviderResult<Option<EpochNanoseconds>> {
260+
(**self).get_time_zone_transition(id, epoch_nanoseconds, direction)
261+
}
262+
}
263+
};
264+
}
265+
266+
provider_deref_impl!(&P);
267+
provider_deref_impl!(&mut P);
268+
provider_deref_impl!(alloc::boxed::Box<P>);
269+
provider_deref_impl!(alloc::rc::Rc<P>);
270+
#[cfg(target_has_atomic = "ptr")]
271+
provider_deref_impl!(alloc::sync::Arc<P>);
272+
214273
/// An id for a resolved timezone, for use with a [`TimeZoneNormalizer`]
215274
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
216275
pub struct NormalizedId(pub usize);
@@ -226,6 +285,37 @@ pub trait TimeZoneNormalizer {
226285
fn identifier(&self, _: NormalizedId) -> TimeZoneProviderResult<&str>;
227286
}
228287

288+
macro_rules! normalizer_deref_impl {
289+
($target:ty) => {
290+
impl<P> TimeZoneNormalizer for $target
291+
where
292+
P: TimeZoneNormalizer + ?Sized,
293+
{
294+
#[inline]
295+
fn normalized(&self, name: &[u8]) -> TimeZoneProviderResult<NormalizedId> {
296+
(**self).normalized(name)
297+
}
298+
299+
#[inline]
300+
fn canonicalized(&self, id: NormalizedId) -> TimeZoneProviderResult<NormalizedId> {
301+
(**self).canonicalized(id)
302+
}
303+
304+
#[inline]
305+
fn identifier(&self, id: NormalizedId) -> TimeZoneProviderResult<&str> {
306+
(**self).identifier(id)
307+
}
308+
}
309+
};
310+
}
311+
312+
normalizer_deref_impl!(&P);
313+
normalizer_deref_impl!(&mut P);
314+
normalizer_deref_impl!(alloc::boxed::Box<P>);
315+
normalizer_deref_impl!(alloc::rc::Rc<P>);
316+
#[cfg(target_has_atomic = "ptr")]
317+
normalizer_deref_impl!(alloc::sync::Arc<P>);
318+
229319
/// An id for a resolved timezone, for use with a [`TimeZoneResolver`]
230320
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
231321
pub struct ResolvedId(pub usize);
@@ -254,6 +344,53 @@ pub trait TimeZoneResolver {
254344
) -> TimeZoneProviderResult<Option<EpochNanoseconds>>;
255345
}
256346

347+
macro_rules! resolver_deref_impl {
348+
($target:ty) => {
349+
impl<P> TimeZoneResolver for $target
350+
where
351+
P: TimeZoneResolver + ?Sized,
352+
{
353+
fn get_id(&self, normalized_identifier: &[u8]) -> TimeZoneProviderResult<ResolvedId> {
354+
(**self).get_id(normalized_identifier)
355+
}
356+
357+
fn candidate_nanoseconds_for_local_epoch_nanoseconds(
358+
&self,
359+
identifier: ResolvedId,
360+
local_datetime: IsoDateTime,
361+
) -> TimeZoneProviderResult<CandidateEpochNanoseconds> {
362+
(**self)
363+
.candidate_nanoseconds_for_local_epoch_nanoseconds(identifier, local_datetime)
364+
}
365+
366+
fn transition_nanoseconds_for_utc_epoch_nanoseconds(
367+
&self,
368+
identifier: ResolvedId,
369+
epoch_nanoseconds: i128,
370+
) -> TimeZoneProviderResult<UtcOffsetSeconds> {
371+
(**self)
372+
.transition_nanoseconds_for_utc_epoch_nanoseconds(identifier, epoch_nanoseconds)
373+
}
374+
375+
fn get_time_zone_transition(
376+
&self,
377+
identifier: ResolvedId,
378+
epoch_nanoseconds: i128,
379+
direction: TransitionDirection,
380+
) -> TimeZoneProviderResult<Option<EpochNanoseconds>> {
381+
(**self).get_time_zone_transition(identifier, epoch_nanoseconds, direction)
382+
}
383+
}
384+
};
385+
}
386+
387+
resolver_deref_impl!(&P);
388+
resolver_deref_impl!(&mut P);
389+
resolver_deref_impl!(alloc::boxed::Box<P>);
390+
resolver_deref_impl!(alloc::rc::Rc<P>);
391+
#[cfg(target_has_atomic = "ptr")]
392+
resolver_deref_impl!(alloc::sync::Arc<P>);
393+
257394
/// A type that can both normalize and resolve, which implements [`TimeZoneProvider`]
258395
#[derive(Default, Copy, Clone, Debug)]
259396
pub struct NormalizerAndResolver<C, R> {

0 commit comments

Comments
 (0)