package main import ( "time" ) type Typed func(*Timer) string type Timer struct { config Config From time.Time Typed Typed paused bool offset time.Duration } func NewTimer(config Config) (*Timer, error) { t := &Timer{From: time.Now().Add(time.Duration(-1) * config.Offset), config: config} return t, t.setTyped(config) } func (t *Timer) TogglePause() { if t.paused { t.Resume() } else { t.Pause() } } func (t *Timer) Resume() { t.paused = false t.From = time.Now().Add(time.Duration(-1) * t.offset) t.offset = 0 } func (t *Timer) Pause() { t.paused = true t.offset = time.Since(t.From) } func (t *Timer) setTyped(config Config) error { if config.Stopwatch { t.Typed = NewBasicStopwatch } else { t.Typed = NewBasicTimer } if config.ETA { t.Typed = WithETA(t.Typed) } if config.Done { t.Typed = WithDone(t.Typed) } if config.TS { t.Typed = WithTS(t.Typed) } return nil } func (t *Timer) Remaining() time.Duration { return time.Until(t.Deadline()) + time.Second } func (t *Timer) Deadline() time.Time { from := t.From if t.paused { from = time.Now().Add(time.Duration(-1) * t.offset) } return from.Add(t.config.Duration) } func (t *Timer) Ack() { for t.Done() { t.From = t.From.Add(t.config.Duration) } } func (t *Timer) Reset() { t.From = time.Now() } func (t *Timer) Done() bool { return time.Now().After(t.From.Add(t.config.Duration)) } func (t *Timer) String() string { return t.Typed(t) } func (t *Timer) Add(d time.Duration) { t.From = t.From.Add(d) } func (t *Timer) Sub(d time.Duration) { t.Add(time.Duration(-1) * d) }