@@ -74,8 +74,8 @@ pub struct Tick {
74
74
impl ClockTimer {
75
75
/// Gets a [`ClockTimer`] builder
76
76
#[ inline]
77
- pub fn builder ( ) -> builder :: Builder {
78
- builder :: Builder :: new ( )
77
+ pub fn builder ( ) -> builder2 :: Builder {
78
+ builder2 :: Builder :: new ( )
79
79
}
80
80
81
81
/// Runs the next tick and returns timing information for it, if this
@@ -306,3 +306,100 @@ pub mod builder {
306
306
}
307
307
}
308
308
}
309
+
310
+ pub mod builder2 {
311
+ use super :: * ;
312
+
313
+ pub struct MarkerUninit {
314
+ __private : ( )
315
+ }
316
+
317
+ pub struct MarkerInit {
318
+ __private : ( )
319
+ }
320
+
321
+ #[ repr( transparent) ]
322
+ pub struct Builder <
323
+ Start = MarkerUninit ,
324
+ End = MarkerUninit ,
325
+ Interval = MarkerUninit
326
+ > {
327
+ inner : BuilderInner ,
328
+ __marker : PhantomData < ( Start , End , Interval ) >
329
+ }
330
+
331
+ struct BuilderInner {
332
+ start : MaybeUninit < DateTime < Local > > ,
333
+ end : MaybeUninit < DateTime < Local > > ,
334
+ interval : MaybeUninit < TimeDelta >
335
+ }
336
+
337
+ impl Builder {
338
+ #[ expect( clippy:: new_without_default, reason = "api design" ) ]
339
+ #[ inline]
340
+ pub fn new ( ) -> Builder {
341
+ Builder {
342
+ inner : BuilderInner {
343
+ start : MaybeUninit :: uninit ( ) ,
344
+ end : MaybeUninit :: uninit ( ) ,
345
+ interval : MaybeUninit :: uninit ( )
346
+ } ,
347
+ __marker : PhantomData
348
+ }
349
+ }
350
+ }
351
+
352
+ impl < End , Interval > Builder < MarkerUninit , End , Interval > {
353
+ #[ inline]
354
+ pub fn with_start_datetime < TZ : TimeZone > ( mut self , datetime : DateTime < TZ > ) -> Builder < MarkerInit , End , Interval > {
355
+ self . inner . start . write ( datetime. with_timezone ( & Local ) ) ;
356
+ Builder { inner : self . inner , __marker : PhantomData }
357
+ }
358
+ }
359
+
360
+ impl < Start , Interval > Builder < Start , MarkerUninit , Interval > {
361
+ #[ inline]
362
+ pub fn with_end_datetime < TZ : TimeZone > ( mut self , datetime : DateTime < TZ > ) -> Builder < Start , MarkerInit , Interval > {
363
+ self . inner . end . write ( datetime. with_timezone ( & Local ) ) ;
364
+ Builder { inner : self . inner , __marker : PhantomData }
365
+ }
366
+ }
367
+
368
+ impl < Interval > Builder < MarkerInit , MarkerUninit , Interval > {
369
+ #[ inline]
370
+ pub fn with_duration ( mut self , duration : TimeDelta ) -> Builder < MarkerInit , MarkerInit , Interval > {
371
+ // SAFETY: enforced by type system (typestate pattern)
372
+ let start = unsafe { self . inner . start . assume_init ( ) } ;
373
+
374
+ self . inner . end . write ( start + duration) ;
375
+ Builder { inner : self . inner , __marker : PhantomData }
376
+ }
377
+ }
378
+
379
+ impl < Start , End > Builder < Start , End , MarkerUninit > {
380
+ #[ inline]
381
+ pub fn with_interval ( mut self , interval : TimeDelta ) -> Builder < Start , End , MarkerInit > {
382
+ self . inner . interval . write ( interval) ;
383
+ Builder { inner : self . inner , __marker : PhantomData }
384
+ }
385
+ }
386
+
387
+ impl Builder < MarkerInit , MarkerInit , MarkerInit > {
388
+ #[ inline]
389
+ pub fn build ( self ) -> ClockTimer {
390
+ // SAFETY: enforced by type system (typestate pattern)
391
+ let start = unsafe { self . inner . start . assume_init ( ) } ;
392
+ // SAFETY: enforced by type system (typestate pattern)
393
+ let end = unsafe { self . inner . end . assume_init ( ) } ;
394
+ // SAFETY: enforced by type system (typestate pattern)
395
+ let interval = unsafe { self . inner . interval . assume_init ( ) } ;
396
+
397
+ ClockTimer {
398
+ next_tick : start,
399
+ interval,
400
+ elapsed : TimeDelta :: zero ( ) ,
401
+ remaining : end - start
402
+ }
403
+ }
404
+ }
405
+ }
0 commit comments