Skip to content

Commit

Permalink
feat: add the 'omitnil' struct field's option
Browse files Browse the repository at this point in the history
  • Loading branch information
wI2L committed Feb 17, 2020
1 parent 53f809f commit fa894ec
Show file tree
Hide file tree
Showing 10 changed files with 132 additions and 60 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ All notable changes to this project are documented in this file.

**THIS LIBRARY IS STILL IN ALPHA AND THERE ARE NO GUARANTEES REGARDING API STABILITY YET**

## [v0.7.0] - 2020-02-17
- Add the `omitnil` field tag's option, which specifies that a field with a nil pointer should be omitted from the encoding. This option has precedence over the `omitempty` option. See this issue for more informations about the original proposal: golang.org/issue/22480.

## [v0.6.0] - 2020-02-14
- Add support for the `sync.Map` type. The marshaling behavior for this type is similar to the one of the Go `map`.

Expand All @@ -16,7 +19,7 @@ This includes the following changes, but not limited to:
- Improve the marshaling performances of many types.
- Add support for marshaling `json.RawMessage` values.
- Add new options `DenyList`, `NoNumberValidation`, `NoCompact`, and rename some others.
- Replace the `Marshaler` and `MarshalerCtx` interfaces by `AppendMarshaler` and `AppendMarshalerCtx` to follow the new *append* model.
- Replace the `Marshaler` and `MarshalerCtx` interfaces by `AppendMarshaler` and `AppendMarshalerCtx` to follow the new *append* model. See this issue on GitHub for more details: golang.org/issue/34701.
- Remove the `IntegerBase` option, which didn't worked properly with the `string` JSON tag.

> Some of the improvements have been inspired by the **github.com/segmentio/encoding** project.
Expand Down Expand Up @@ -53,6 +56,7 @@ This includes the following changes, but not limited to:
## [v0.1.0] - 2019-08-30
Initial realease.

[v0.7.0]: https://github.com/wI2L/jettison/compare/v0.6.0...v0.7.0
[v0.6.0]: https://github.com/wI2L/jettison/compare/v0.5.0...v0.6.0
[v0.5.0]: https://github.com/wI2L/jettison/compare/v0.4.1...v0.5.0
[v0.4.1]: https://github.com/wI2L/jettison/compare/v0.4.0...v0.4.1
Expand Down
78 changes: 40 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

Jettison uses the new [Go modules](https://github.com/golang/go/wiki/Modules). Releases are tagged according to the _SemVer_ format, prefixed with a `v`, starting from *0.2.0*. You can get the latest release using the following command.

```sh
```console
$ go get github.com/wI2L/jettison
```

Expand Down Expand Up @@ -53,6 +53,8 @@ All notable differences with the standard library behavior are listed below. Ple

- The `sync.Map` type is handled natively. The marshaling behavior is similar to the one of a standard Go `map`. The option `UnsortedMap` can also be used in cunjunction with this type to disable the default keys sort.

- The `omitnil` field tag's option can be used to specify that a field with a nil pointer should be omitted from the encoding. This option has precedence over the `omitempty` option.

##### Bugs

- Nil map keys values implementing the `encoding.TextMarshaler` interface are encoded as empty strings, while the `encoding/json` package currently panic because of that. See this [issue](https://github.com/golang/go/issues/33675) for more details.<sup>[1]</sup>
Expand Down Expand Up @@ -128,47 +130,47 @@ OS: macOS Mojave (10.14.6)
CPU: 2.6 GHz Intel Core i7
Mem: 16GB
Go: go version go1.13.7 darwin/amd64
Tag: v0.5.0
Tag: v0.7.0
```

<details><summary>Stats</summary><br><pre>
name time/op
Simple/standard-8 666ns ± 4%
Simple/jsoniter-8 770ns ± 1%
Simple/segmentj-8 376ns ± 0%
Simple/jettison-8 485ns ± 1%
Simple/standard-8 662ns ± 1%
Simple/jsoniter-8 775ns ± 1%
Simple/segmentj-8 380ns ± 1%
Simple/jettison-8 472ns ± 1%
Complex/standard-8 13.8µs ± 1%
Complex/jsoniter-8 14.1µs ± 2%
Complex/segmentj-8 9.77µs ± 2%
Complex/jettison-8 6.84µs ± 1%
CodeMarshal/standard-8 7.27ms ± 1%
CodeMarshal/jsoniter-8 8.28ms ± 1%
CodeMarshal/segmentj-8 5.55ms ± 0%
CodeMarshal/jettison-8 5.99ms ± 1%
Map/standard-8 2.19µs ± 0%
Map/jsoniter-8 1.84µs ± 1%
Complex/jsoniter-8 14.1µs ± 1%
Complex/segmentj-8 9.72µs ± 1%
Complex/jettison-8 6.86µs ± 1%
CodeMarshal/standard-8 7.25ms ± 0%
CodeMarshal/jsoniter-8 8.27ms ± 1%
CodeMarshal/segmentj-8 5.54ms ± 0%
CodeMarshal/jettison-8 6.02ms ± 0%
Map/standard-8 2.19µs ± 1%
Map/jsoniter-8 1.83µs ± 1%
Map/segmentj-8 1.92µs ± 0%
Map/jettison-8 917ns ± 1%
Map/jettison-nosort-8 607ns ± 2%
Map/jettison-8 904ns ± 1%
Map/jettison-nosort-8 600ns ± 1%

name speed
Simple/standard-8 203MB/s ± 4%
Simple/jsoniter-8 175MB/s ± 1%
Simple/segmentj-8 359MB/s ± 0%
Simple/jettison-8 278MB/s ± 1%
Simple/standard-8 204MB/s ± 1%
Simple/jsoniter-8 174MB/s ± 1%
Simple/segmentj-8 355MB/s ± 2%
Simple/jettison-8 286MB/s ± 1%
Complex/standard-8 61.8MB/s ± 1%
Complex/jsoniter-8 58.1MB/s ± 2%
Complex/segmentj-8 88.1MB/s ± 2%
Complex/jettison-8 124MB/s ± 2%
CodeMarshal/standard-8 267MB/s ± 1%
CodeMarshal/jsoniter-8 234MB/s ± 1%
CodeMarshal/segmentj-8 349MB/s ± 0%
CodeMarshal/jettison-8 324MB/s ± 1%
Map/standard-8 38.9MB/s ± 0%
Map/jsoniter-8 46.2MB/s ± 1%
Map/segmentj-8 44.2MB/s ± 1%
Map/jettison-8 92.7MB/s ± 1%
Map/jettison-nosort-8 140MB/s ± 2%
Complex/jsoniter-8 58.1MB/s ± 1%
Complex/segmentj-8 88.5MB/s ± 1%
Complex/jettison-8 124MB/s ± 1%
CodeMarshal/standard-8 268MB/s ± 0%
CodeMarshal/jsoniter-8 235MB/s ± 1%
CodeMarshal/segmentj-8 350MB/s ± 0%
CodeMarshal/jettison-8 322MB/s ± 0%
Map/standard-8 38.9MB/s ± 1%
Map/jsoniter-8 46.4MB/s ± 1%
Map/segmentj-8 44.3MB/s ± 0%
Map/jettison-8 94.0MB/s ± 1%
Map/jettison-nosort-8 142MB/s ± 1%

name alloc/op
Simple/standard-8 144B ± 0%
Expand All @@ -179,12 +181,12 @@ Complex/standard-8 4.76kB ± 0%
Complex/jsoniter-8 4.65kB ± 0%
Complex/segmentj-8 3.25kB ± 0%
Complex/jettison-8 1.38kB ± 0%
CodeMarshal/standard-8 1.96MB ± 1%
CodeMarshal/jsoniter-8 1.99MB ± 5%
CodeMarshal/segmentj-8 1.98MB ± 2%
CodeMarshal/jettison-8 1.98MB ± 2%
CodeMarshal/standard-8 1.95MB ± 1%
CodeMarshal/jsoniter-8 1.99MB ± 2%
CodeMarshal/segmentj-8 1.97MB ± 2%
CodeMarshal/jettison-8 1.97MB ± 2%
Map/standard-8 848B ± 0%
Map/jsoniter-8 924B ± 0%
Map/jsoniter-8 925B ± 0%
Map/segmentj-8 592B ± 0%
Map/jettison-8 96.0B ± 0%
Map/jettison-nosort-8 160B ± 0%
Expand Down
9 changes: 7 additions & 2 deletions encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ fieldLoop:
// Find the nested struct field by following
// the offset sequence, indirecting encountered
// pointers as needed.
for _, s := range f.embedSeqs {
for _, s := range f.embedSeq {
v = unsafe.Pointer(uintptr(v) + s.offset)
if s.indir {
if v = *(*unsafe.Pointer)(v); v == nil {
Expand All @@ -219,8 +219,13 @@ fieldLoop:
}
}
}
// Ignore the field if it is a nil pointer and has
// the omitnil option in his tag.
if f.omitNil && *(*unsafe.Pointer)(v) == nil {
continue
}
// Ignore the field if it represents the zero-value
// of its type and has the omitempty option in its tag.
// of its type and has the omitempty option in his tag.
// Empty func is non-nil only if the field has the
// omitempty option in its tag.
if f.omitEmpty && f.empty(v) {
Expand Down
2 changes: 1 addition & 1 deletion images/benchmarks/code-marshal.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion images/benchmarks/map.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit fa894ec

Please sign in to comment.