Skip to content

doc: describe json and yaml marshalling - #17

Merged
oleg-jukovec merged 9 commits into
masterfrom
bigbes/gh-no-json-marshalling
Sep 30, 2026
Merged

oleg-jukovec merged 9 commits into
masterfrom
bigbes/gh-no-json-marshalling

Conversation

@bigbes

@bigbes bigbes commented Sep 25, 2026 •

Copy link
Copy Markdown
Collaborator

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.

  • generator: add json and yaml marshalling - 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. 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.
  • option: add json and yaml marshalling to Generic - The value is handed over through a pointer, so methods of T with a pointer receiver (MarshalJSON, MarshalText) are honoured.
  • gentypes: add json and yaml marshalling - Optional types generated for other packages (go-tarantool's OptionalDatetime, OptionalDecimal, OptionalBoxError and others) get the same methods; generated code gains no dependency.
  • doc: describe json and yaml marshalling

@bigbes

bigbes commented Sep 25, 2026 •

Copy link
Copy Markdown
Collaborator Author

Review links (diffshub):

Whole PR: https://diffshub.com/tarantool/go-option/pull/17

@coveralls

coveralls commented Sep 25, 2026 •

Copy link
Copy Markdown

Coverage Status

coverage: 94.502% (+2.9%) from 91.637% — bigbes/gh-no-json-marshalling into master

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
bigbes force-pushed the bigbes/gh-no-json-marshalling branch from 5e96956 to 981763c Compare September 27, 2026 19:28
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
bigbes force-pushed the bigbes/gh-no-json-marshalling branch from 981763c to 5b3cd3d Compare September 28, 2026 06:46

@oleg-jukovec oleg-jukovec left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

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.

@oleg-jukovec
oleg-jukovec merged commit c5f1165 into master Sep 30, 2026
15 checks passed
@oleg-jukovec
oleg-jukovec deleted the bigbes/gh-no-json-marshalling branch September 30, 2026 08:37
@bigbes bigbes mentioned this pull request Oct 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants