diff --git a/ulid.go b/ulid.go index 2064dd4..77e9ddd 100644 --- a/ulid.go +++ b/ulid.go @@ -75,6 +75,9 @@ var ( // ErrScanValue is returned when the value passed to scan cannot be unmarshaled // into the ULID. ErrScanValue = errors.New("ulid: source value must be a string or byte slice") + + // Zero is a zero-value ULID. + Zero ULID ) // MonotonicReader is an interface that should yield monotonically increasing @@ -416,6 +419,11 @@ func (id ULID) Timestamp() time.Time { return Time(id.Time()) } +// IsZero returns true if the ULID is a zero-value ULID, i.e. ulid.Zero. +func (id ULID) IsZero() bool { + return id.Compare(Zero) == 0 +} + // maxTime is the maximum Unix time in milliseconds that can be // represented in a ULID. var maxTime = ULID{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}.Time() diff --git a/ulid_test.go b/ulid_test.go index 43f81c6..5ca70ae 100644 --- a/ulid_test.go +++ b/ulid_test.go @@ -454,6 +454,20 @@ func TestULIDTimestamp(t *testing.T) { } } +func TestZero(t *testing.T) { + t.Parallel() + + var id ulid.ULID + if ok := id.IsZero(); !ok { + t.Error(".IsZero: must return true for zero-value ULIDs, have false") + } + + id = ulid.MustNew(ulid.Now(), ulid.DefaultEntropy()) + if ok := id.IsZero(); ok { + t.Error(".IsZero: must return false for non-zero-value ULIDs, have true") + } +} + func TestEntropy(t *testing.T) { t.Parallel()