Repository: gofrs/uuid

Issue:
Create a new MongoDB method IsZero similar to IsNull to support omitzero tag
### Welcome

- [x] Yes, I've searched similar issues on GitHub and didn't find any.

### Detailed Description

I need a new MongoDB-specific method to be created, called IsZero, similar to the existing IsNull method, to support the MongoDB omitzero tag functionality. This would enable proper handling of zero values in MongoDB operations when using the omitzero tag in struct fields.

This is specifically for MongoDB driver functionality, not for the Go standard library's omitzero implementation.

Hints from issue comments:
@dylan-bourque: This shouldn't be necessary since [uuid.Nil](https://github.com/gofrs/uuid/blob/master/uuid.go#L159) is already a zero value of the `UUID` type.

From the docs for `encoding/json/v2`:

> When marshaling, the "omitzero" option specifies that the struct field should be omitted if the field value is zero as determined by the "IsZero() bool" method if present, otherwise **based on whether the field is the zero Go value**.

The 2nd case (emphasis added) would apply.

@AndreCDiniz: @dylan-bourque 
In v1, when marshaling a Go struct, a field marked as `omitempty` is omitted if the field value is an "empty" Go value, which is defined as false, 0, a nil pointer, a nil interface value, and any empty array, slice, map, or string. In contrast, v2 redefines `omitempty` to omit a field if it encodes as an "empty" JSON value, which is defined as a JSON null, or an empty JSON string, object, or array. The OmitEmptyWithLegacySemantics option controls this behavior difference. Note that `omitempty` behaves identically in both v1 and v2 for a Go array, slice, map, or string (assuming no user-defined MarshalJSON method overrides the default representation). Existing usages of `omitempty` on a Go bool, number, pointer, or interface value should migrate to specifying `omitzero` instead (which is identically supported in both v1 and v2). 

The omitzero functionality is already a standard feature in Go 1.24, as part of the v1 version of the encoding/json package.

https://tip.golang.org/doc/go1.24#encodingjsonpkgencodingjson
and
https://pkg.go.dev/encoding/json@master@dylan-bourque: Right, but it's not necessary to have an explicit `IsZero()` method for the `omitzero` tag to work.  If that method doesn't exist, then the value is omitted if the value is a zero value.

From the 1.24 release notes that you linked:
> If the field type has an `IsZero() bool` method, that will be used to determine whether the value is zero. Otherwise, the value is zero if it is [the zero value for its type](https://tip.golang.org/ref/spec#The_zero_value).

In this case, adding the method isn't required since `uuid.Nil` is a zero value of the `UUID` type.@AndreCDiniz: ok, it might work with json but this won't work with bson documents as stated in mongo documents, the type needs to implement Zeroer interface which is the IsZero (bool) method

omitempty: If the "omitempty" struct tag is specified on a field, the field will not be marshaled if it is set to an "empty" value. Numbers, booleans, and strings are considered empty if their value is equal to the zero value for the type (i.e. 0 for numbers, false for booleans, and "" for strings). Slices, maps, and arrays are considered empty if they are of length zero. Interfaces and pointers are considered empty if their value is nil. By default, structs are only considered empty if the struct type implements bsoncodec.Zeroer and the IsZero method returns true. Struct types that do not implement bsoncodec.Zeroer are never considered empty and will be marshaled as embedded documents. NOTE: It is recommended that this tag be used for all slice and map fields. 

https://pkg.go.dev/go.mongodb.org/mongo-driver/bson@dylan-bourque: Ah.  Supporting a specific MongoDB feature is very different than supporting things defined in the Go standard library.  Can you please update the description and title to reflect that this request is for MongoDB and not `omitzero` as defined by the standard library?

FWIW, I would personally argue that `bsoncodec` should be updated to behave like the standard library. 🤷‍♂️ @AndreCDiniz: Done.@AndreCDiniz: Bump. Any news?@cameracker: I'll get to this eventually but I'm a little strapped for time. I'm sort of curious what copilot will do if I give it a very specific prompt so might mess around with that (at risk of incurring the rage of anti AI folks 😅 )

Solution patch:
diff --git a/uuid.go b/uuid.go
index 990debd..bd59d48 100644
--- a/uuid.go
+++ b/uuid.go
@@ -192,6 +192,13 @@ func (u UUID) IsNil() bool {
 	return u == Nil
 }
 
+// IsZero returns if the UUID is equal to the zero UUID (same as IsNil).
+// This method is provided to satisfy the bsoncodec.Zeroer interface for MongoDB
+// omitzero tag support. See: https://github.com/gofrs/uuid/issues/224
+func (u UUID) IsZero() bool {
+	return u == Nil
+}
+
 // Version returns the algorithm version used to generate the UUID.
 func (u UUID) Version() byte {
 	return u[6] >> 4



Test patch:
diff --git a/uuid_test.go b/uuid_test.go
index d1cc108..f97ddae 100644
--- a/uuid_test.go
+++ b/uuid_test.go
@@ -31,6 +31,7 @@ import (
 
 func TestUUID(t *testing.T) {
 	t.Run("IsNil", testUUIDIsNil)
+	t.Run("IsZero", testUUIDIsZero)
 	t.Run("Bytes", testUUIDBytes)
 	t.Run("String", testUUIDString)
 	t.Run("Version", testUUIDVersion)
@@ -49,6 +50,24 @@ func testUUIDIsNil(t *testing.T) {
 	}
 }
 
+func testUUIDIsZero(t *testing.T) {
+	// Test zero UUID
+	u := UUID{}
+	got := u.IsZero()
+	want := true
+	if got != want {
+		t.Errorf("%v.IsZero() = %t, want %t", u, got, want)
+	}
+
+	// Test non-zero UUID
+	nonZeroUUID := NamespaceDNS // Use a known non-zero UUID
+	got = nonZeroUUID.IsZero()
+	want = false
+	if got != want {
+		t.Errorf("%v.IsZero() = %t, want %t", nonZeroUUID, got, want)
+	}
+}
+
 func testUUIDBytes(t *testing.T) {
 	got := codecTestUUID.Bytes()
 	want := codecTestData