Repository navigation
doc: describe json and yaml marshalling - #17
Merged
Merged
Conversation
Collaborator
Author
|
Review links (diffshub):
|
golangci-lint v2.14 replaced exhaustruct with exhaustruct_v5, made wsl_v5 stricter about blank lines and goconst about repeated strings, so the code that passed v2.x before no longer does. - None spells out every field instead of relying on a nolint directive for the deprecated exhaustruct. - Blank lines are added where wsl_v5 now requires them. - goconst is excluded for tests and the generator's type table: both repeat testing values on purpose, and they read better inline.
The action installed the latest golangci-lint, so a new release could turn the check red without any change in the repository. Pin it to v2.14.0 and bump it deliberately.
bigbes
force-pushed
the
bigbes/gh-no-json-marshalling
branch
from
September 27, 2026 19:28
5e96956 to
981763c
Compare
Optional types keep their state in unexported fields, so encoding/json
wrote every one of them as {} and the value was lost; YAML encoders
did the same.
- MarshalJSON encodes an absent value as null and a present one exactly
as json.Marshal encodes the inner value.
- UnmarshalJSON decodes null as an absent value and any other JSON value
into the inner type; errors of the inner type are returned unchanged.
- MarshalYAML and UnmarshalYAML use the interfaces gopkg.in/yaml.v3
accepts without importing it; yaml.v3 never calls UnmarshalYAML for a
null node, so null into a present value keeps it.
- Generated tests cover round trips, zero values that must stay distinct
from an absent value, struct fields and the omitzero/omitempty tag
options.
Run go generate, so every builtin optional type gains MarshalJSON, UnmarshalJSON, MarshalYAML and UnmarshalYAML, and the tests for them. The generated tests import gopkg.in/yaml.v3, so it becomes a direct test dependency and depguard allows it in tests.
Generic[T] had the same problem as the generated types: encoding/json
and YAML encoders saw no exported fields and wrote {} for any value.
- MarshalJSON, UnmarshalJSON, MarshalYAML and UnmarshalYAML follow the
generated types: null for None, the plain encoding of T for Some.
- The value is handed over through a pointer, so methods of T with a
pointer receiver (MarshalJSON, MarshalText) are honoured.
- commonInterface now requires all four methods, so every optional type
is checked for them at compile time.
Optional types generated for other packages (go-tarantool's
OptionalDatetime, OptionalDecimal, OptionalBoxError and others) were
written by encoding/json and YAML encoders as {}, losing the value.
- The template emits MarshalJSON, UnmarshalJSON, MarshalYAML and
UnmarshalYAML with the same semantics as the builtin types: null for
None, the plain encoding of the wrapped type for Some.
- The wrapped value is handed over through a pointer, so a MarshalJSON
or MarshalText with a pointer receiver is honoured.
- The YAML methods use the interfaces gopkg.in/yaml.v3 accepts without
importing it, so generated code gains no dependency.
- Compile-time assertions check the generated type implements
json.Marshaler and json.Unmarshaler.
Run go generate, so the test types gain the JSON and YAML methods the template now emits.
- Tests cover round trips, None and null, decoding errors and struct fields for the generated test types. - A PointerTextType fixture covers a wrapped type whose MarshalJSON and MarshalText have a pointer receiver.
Explain what optional types look like in JSON and YAML, since the choices are not obvious from the method signatures. - The README documents null for None, the plain encoding of the wrapped value for Some, the nil-inside-Some caveat, omitzero and omitempty. - It states why there is no MarshalText and that yaml.v3 skips UnmarshalYAML for null nodes, leaving a present value in place. - The changelog gets an entry under Unreleased.
bigbes
force-pushed
the
bigbes/gh-no-json-marshalling
branch
from
September 28, 2026 06:46
981763c to
5b3cd3d
Compare
oleg-jukovec
approved these changes
Sep 29, 2026
oleg-jukovec
left a comment
Collaborator
There was a problem hiding this comment.
LGTM, but please fix the PR title/description: this PR isn't about documentation; it's about new functionality. So the PR title is confusing.
patapenka-alexey
approved these changes
Sep 30, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Optional types keep their state in unexported fields, so encoding/json wrote every one of them as {} and the value was lost; YAML encoders did the same.