Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GODRIVER-1765 Improve JSON marshaling/unmarshaling for bson.D, bson.M and bson.A. #1594

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

qingyang-hu
Copy link
Collaborator

GODRIVER-1765

Summary

This PR adds json.Marshaler and json.Unmarshaler for primitive.D, so it can handle JSON objects properly.
The PR also adds json.Unmarshalers for primitive.M and primitive.A, so JSON strings can be unmarshaled into nested structures correspondingly.

After the "primitive" merging into "bson" package, we can migrate these primitive methods to their bson types.

Copy link

API Change Report

./bson/primitive

compatible changes

(*A).UnmarshalJSON: added
(*D).UnmarshalJSON: added
(*M).UnmarshalJSON: added
D.MarshalJSON: added

prestonvasquez
prestonvasquez previously approved these changes Apr 15, 2024
Copy link
Collaborator

@prestonvasquez prestonvasquez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Comment on lines 241 to 258
dec := json.NewDecoder(bytes.NewReader(b))
t, err := dec.Token()
if err != nil {
return err
}
if t == nil {
*d = nil
return nil
}
if v, ok := t.(json.Delim); !ok || v != '{' {
return &json.UnmarshalTypeError{
Value: tokenString(t),
Type: reflect.TypeOf(*d),
Offset: dec.InputOffset(),
}
}
*d, err = jsonDecodeD(dec)
return err
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Optional] You could combine the logic in D.UnmarshalJSON and m.UnmarshalJSON using generics:

func newJsonObjDecoder[T D | M](b []byte, val *T) (*json.Decoder, error) {
	dec := json.NewDecoder(bytes.NewReader(b))

	t, err := dec.Token()
	if err != nil {
		return nil, err
	}

	if t == nil {
		*val = nil
		return nil, nil
	}

	if v, ok := t.(json.Delim); !ok || v != '{' {
		return nil, &json.UnmarshalTypeError{
			Value:  tokenString(t),
			Type:   reflect.TypeOf(*val),
			Offset: dec.InputOffset(),
		}
	}

	return dec, nil
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
priority-3-low Low Priority PR for Review
Projects
None yet
2 participants