Skip to content

Commit

Permalink
added Must versions of panicking methods
Browse files Browse the repository at this point in the history
  • Loading branch information
Semior001 committed Dec 25, 2021
1 parent 565e4b4 commit 2a39268
Show file tree
Hide file tree
Showing 5 changed files with 313 additions and 190 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ betweenRng := trn.Between(time.Now(), time.Now().Add(3 * time.Hour), trn.In(time

For more examples see [test file](examples_test.go).

## Todo
- [ ] Make UTC and opts tests work in UTC location

## Methods
- `func New(start time.Time, duration time.Duration, opts ...Option) Range`

Expand Down
4 changes: 3 additions & 1 deletion examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ func TestMergeRanges(t *testing.T) {
now := time.Now()

rng := New(now, time.Hour+3*time.Minute)
ranges := rng.Stratify(15*time.Minute, 5*time.Minute)
ranges, err := rng.Stratify(15*time.Minute, 5*time.Minute)
assert.NoError(t, err)

assert.Equal(t, []Range{
New(now, 15*time.Minute),
New(now.Add(5*time.Minute), 15*time.Minute),
Expand Down
86 changes: 43 additions & 43 deletions operations_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,83 +14,83 @@ func TestMergeOverlappingRanges(t *testing.T) {
{
name: "ranges don't overlap",
args: []Range{
Between(tm(13, 0), tm(14, 0)),
Between(tm(15, 0), tm(16, 0)),
MustBetween(tm(13, 0), tm(14, 0)),
MustBetween(tm(15, 0), tm(16, 0)),
},
want: []Range{
Between(tm(13, 0), tm(14, 0)),
Between(tm(15, 0), tm(16, 0)),
MustBetween(tm(13, 0), tm(14, 0)),
MustBetween(tm(15, 0), tm(16, 0)),
},
},
{
name: "ranges intersect",
args: []Range{
Between(tm(13, 0), tm(14, 0)),
Between(tm(13, 30), tm(15, 0)),
MustBetween(tm(13, 0), tm(14, 0)),
MustBetween(tm(13, 30), tm(15, 0)),
},
want: []Range{
Between(tm(13, 0), tm(15, 0)),
MustBetween(tm(13, 0), tm(15, 0)),
},
},
{
name: "one range eternally overlaps the other",
args: []Range{
Between(tm(13, 0), tm(15, 0)),
Between(tm(13, 30), tm(14, 30)),
MustBetween(tm(13, 0), tm(15, 0)),
MustBetween(tm(13, 30), tm(14, 30)),
},
want: []Range{
Between(tm(13, 0), tm(15, 0)),
MustBetween(tm(13, 0), tm(15, 0)),
},
},
{
name: "boundaries of two ranges are equal",
args: []Range{
Between(tm(13, 0), tm(13, 15)),
Between(tm(13, 15), tm(13, 30)),
MustBetween(tm(13, 0), tm(13, 15)),
MustBetween(tm(13, 15), tm(13, 30)),
},
want: []Range{
Between(tm(13, 0), tm(13, 30)),
MustBetween(tm(13, 0), tm(13, 30)),
},
},
{
name: "complex test",
args: []Range{
// next three ranges must be merged (last two are within the first one)
Between(tm(19, 0), tm(19, 30)),
Between(tm(19, 1), tm(19, 15)),
Between(tm(19, 8), tm(19, 17)),
MustBetween(tm(19, 0), tm(19, 30)),
MustBetween(tm(19, 1), tm(19, 15)),
MustBetween(tm(19, 8), tm(19, 17)),
// next second range must be removed (end of first = end of second)
Between(tm(15, 0), tm(15, 30)),
Between(tm(15, 16), tm(15, 30)),
MustBetween(tm(15, 0), tm(15, 30)),
MustBetween(tm(15, 16), tm(15, 30)),
// next two ranges must NOT be merged
Between(tm(12, 0), tm(12, 15)),
Between(tm(12, 30), tm(12, 45)),
MustBetween(tm(12, 0), tm(12, 15)),
MustBetween(tm(12, 30), tm(12, 45)),
// next two ranges must be merged (end of the first = start of the second)
Between(tm(13, 0), tm(13, 15)),
Between(tm(13, 15), tm(13, 30)),
MustBetween(tm(13, 0), tm(13, 15)),
MustBetween(tm(13, 15), tm(13, 30)),
// next two ranges must be merged
Between(tm(14, 0), tm(14, 16)),
Between(tm(14, 15), tm(14, 30)),
MustBetween(tm(14, 0), tm(14, 16)),
MustBetween(tm(14, 15), tm(14, 30)),
// next second range must be removed (start of first = start of second)
Between(tm(16, 0), tm(16, 30)),
Between(tm(16, 0), tm(16, 16)),
MustBetween(tm(16, 0), tm(16, 30)),
MustBetween(tm(16, 0), tm(16, 16)),
// next second range must be removed (ranges are equal)
Between(tm(17, 0), tm(17, 30)),
Between(tm(17, 0), tm(17, 30)),
MustBetween(tm(17, 0), tm(17, 30)),
MustBetween(tm(17, 0), tm(17, 30)),
// next second range must be removed
Between(tm(18, 0), tm(18, 30)),
Between(tm(18, 1), tm(18, 15)),
MustBetween(tm(18, 0), tm(18, 30)),
MustBetween(tm(18, 1), tm(18, 15)),
},
want: []Range{
Between(tm(12, 0), tm(12, 15)),
Between(tm(12, 30), tm(12, 45)),
Between(tm(13, 0), tm(13, 30)),
Between(tm(14, 0), tm(14, 30)),
Between(tm(15, 0), tm(15, 30)),
Between(tm(16, 0), tm(16, 30)),
Between(tm(17, 0), tm(17, 30)),
Between(tm(18, 0), tm(18, 30)),
Between(tm(19, 0), tm(19, 30)),
MustBetween(tm(12, 0), tm(12, 15)),
MustBetween(tm(12, 30), tm(12, 45)),
MustBetween(tm(13, 0), tm(13, 30)),
MustBetween(tm(14, 0), tm(14, 30)),
MustBetween(tm(15, 0), tm(15, 30)),
MustBetween(tm(16, 0), tm(16, 30)),
MustBetween(tm(17, 0), tm(17, 30)),
MustBetween(tm(18, 0), tm(18, 30)),
MustBetween(tm(19, 0), tm(19, 30)),
},
},
}
Expand All @@ -117,11 +117,11 @@ func TestIntersection(t *testing.T) {
{
name: "intersection",
args: []Range{
Between(tm(13, 0), tm(19, 0)),
Between(tm(15, 0), tm(17, 0)),
Between(tm(16, 0), tm(21, 0)),
MustBetween(tm(13, 0), tm(19, 0)),
MustBetween(tm(15, 0), tm(17, 0)),
MustBetween(tm(16, 0), tm(21, 0)),
},
want: Between(tm(16, 0), tm(17, 0)),
want: MustBetween(tm(16, 0), tm(17, 0)),
},
}
for _, tt := range tests {
Expand Down
70 changes: 55 additions & 15 deletions range.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,19 @@ func New(start time.Time, duration time.Duration, opts ...Option) Range {
}

// Between returns the new Range in the given time bounds. Range will use the
// location of the start timestamp. Panics if the start time is later than the
// end time of the range.
func Between(start, end time.Time, opts ...Option) Range {
// location of the start timestamp.
// Returns ErrStartAfterEnd if the start time is later than the end.
func Between(start, end time.Time, opts ...Option) (Range, error) {
if start.After(end) {
panic("start is after the end")
return Range{}, ErrStartAfterEnd
}

res := Range{st: start, dur: end.Sub(start)}
for _, opt := range opts {
opt(&res)
}
return res

return res, nil
}

// Range represents time slot with its own start and end time boundaries
Expand Down Expand Up @@ -90,22 +91,22 @@ func (r Range) Format(layout string) string {

// Split the date range into smaller ranges, with fixed duration and with the
// given interval between the *end* of the one range and *start* of next range.
// In case if the last interval doesn't fit into the given duration, Split won't
// In case if the last interval doesn't fit into the given duration, MustSplit won't
// return it.
func (r Range) Split(duration time.Duration, interval time.Duration) []Range {
if duration == 0 {
panic("cannot split with zero duration")
func (r Range) Split(duration time.Duration, interval time.Duration) ([]Range, error) {
if duration <= 0 {
return nil, ErrZeroDurationInterval
}
return r.Stratify(duration, duration+interval)
}

// Stratify the date range into smaller ranges, with fixed duration and with the
// given interval between the *starts* of the resulting ranges.
// In case if the last interval doesn't fit into the given duration, Stratify
// In case if the last interval doesn't fit into the given duration, MustStratify
// won't return it.
func (r Range) Stratify(duration time.Duration, interval time.Duration) []Range {
if interval == 0 || duration == 0 {
panic("cannot stratify with zero duration or zero interval")
func (r Range) Stratify(duration time.Duration, interval time.Duration) ([]Range, error) {
if interval <= 0 || duration <= 0 {
return nil, ErrZeroDurationInterval
}

var res []Range
Expand All @@ -117,7 +118,7 @@ func (r Range) Stratify(duration time.Duration, interval time.Duration) []Range
rangeStart = rangeStart.Add(interval)
}

return res
return res, nil
}

// Contains returns true if the other date range is within this date range.
Expand Down Expand Up @@ -158,7 +159,7 @@ func (r Range) Truncate(bounds Range) Range {
// --YYY----
return Range{st: r.st, dur: bounds.End().Sub(r.st)}
default:
panic("should never happen")
panic("trn: should never happen")
}
}

Expand Down Expand Up @@ -199,3 +200,42 @@ func (r Range) flipValidRanges(ranges []Range) []Range {

return res
}

// MustSplit does the same as Split, but panics in case of any error.
func (r Range) MustSplit(duration time.Duration, interval time.Duration) []Range {
rngs, err := r.Split(duration, interval)
if err != nil {
panic(err)
}
return rngs
}

// MustStratify does the same as Stratify, but panics in case of any error.
func (r Range) MustStratify(duration time.Duration, interval time.Duration) []Range {
rngs, err := r.Stratify(duration, interval)
if err != nil {
panic(err)
}
return rngs
}

// MustBetween does the same as Between, but panics, instead of returning error.
func MustBetween(start, end time.Time, opts ...Option) Range {
rng, err := Between(start, end, opts...)
if err != nil {
panic(err)
}
return rng
}

// Error describes any error appeared in this package.
type Error string

// Error returns string representation of the error.
func (e Error) Error() string { return string(e) }

// package errors
const (
ErrStartAfterEnd = Error("trn: start time is later than the end")
ErrZeroDurationInterval = Error("trn: cannot split with zero duration or interval")
)
Loading

0 comments on commit 2a39268

Please sign in to comment.