<commit_before>package metrics

import "time"

type Timer struct {
	// A Timer is a Metric.
	*Metric

	// The time that this Timer started.
	Start time.Time

	// The time that this Timer ended.
	End time.Time
}

// NewTimer returns a new Timer.
func NewTimer(metric string) *Timer {
	return &Timer{
		Metric: &Metric{Type: Measurement, Name: metric, Units: "ms"},
		Start:  time.Now(),
	}
}

// Duration returns the duration of this timer.
func (t *Timer) Duration() time.Duration {
	return t.End.Sub(t.Start)
}

// Stop sets End on the Timer and calculates the value for the Metric.
func (t *Timer) Stop() {
	t.Value = t.Duration() * time.Millisecond
}

// Done stops the timer and prints it.
func (t *Timer) Done() {
	t.Stop()
	t.Print()
}<commit_msg>Keep track of whether the timer was stopped.<commit_after>package metrics

import (
	"errors"
	"time"
)

var (
	ErrTimerStopped = errors.New("this timer has already been stopped")
)

type Timer struct {
	// A Timer is a Metric.
	*Metric

	// The time that this Timer started.
	Start time.Time

	// The time that this Timer ended.
	End time.Time

	stopped bool
}

// NewTimer returns a new Timer.
func NewTimer(metric string) *Timer {
	return &Timer{
		Metric: &Metric{Type: Measurement, Name: metric, Units: "ms"},
		Start:  time.Now(),
	}
}

// Duration returns the duration of this timer.
func (t *Timer) Duration() time.Duration {
	return t.End.Sub(t.Start)
}

// Stop sets End on the Timer and calculates the value for the Metric.
func (t *Timer) Stop() {
	t.Value = t.Duration() * time.Millisecond
	t.stopped = true
}

// Done stops the timer and prints it.
func (t *Timer) Done() error {
	if t.stopped {
		return ErrTimerStopped
	}

	t.Stop()
	t.Print()

	return nil
}
{'fraction_non_alphanumeric': 0.12159814707585408, 'fraction_numerical': 0.0, 'mean_word_length': 3.32, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '839115', 'n_tokens_mistral': 618, 'n_tokens_neox': 576, 'n_words': 219}