swallowjson

package module
v1.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 10, 2023 License: MIT Imports: 5 Imported by: 0

README

swallowjson

Continuous Integration Documentation Coverage Status

The swallowjson Golang library provides a simple-to-use support function to use to implement an interface method in your type, to aid in JSON decoding.

When decoding JSON into a struct, the default Golang handling is to discard the JSON fields encountered which have not been declared as struct fields. The UnmarshalWith function lets you implement the UnmarshalJSON method as a one-liner, declaring a map within the struct which should swallow all JSON fields not otherwise accepted by the struct.

A simple example:

type MyType struct {
	Foo  string                 `json:"foo"`
	Bar  int                    `json:"bar"`
	Rest map[string]interface{} `json:"-"`
}

func (mt *MyType) UnmarshalJSON(raw []byte) error {
	return swallowjson.UnmarshalWith(mt, "Rest", raw)
}

You can then decode as normal for Golang, letting the JSON decoder dispatch to your overridden UnmarshalJSON method whenever it expects to decode a MyType (whether at the top-level, or nested inside other types, etc):

var myData MyType
if err := json.Unmarshal(rawBytes, &myData); err != nil {
	processError(err)
}

When invoked on mt, which should already exist as a struct, swallowjson.UnmarshalWith will populate Foo and Bar from JSON fields foo and bar respectively, per normal Golang decoding rules. But if the JSON also contains fields baz and bat then those will end up as keys, holding their child data, in the Rest map.

This library was written as a fairly quick proof-of-concept for a friend and later gained sufficient tests as to be something which can be relied upon as a core component, with no other dependencies. The library is released in the hopes that it might prove useful to others.

Behavior notes:

  • The Golang encoding/json library has a bunch of legacy case-insensitivity handling in the default unmarshaller; while swallowjson builds upon that library (it uses json.NewDecoder() under the hood) our API is a new API, implemented in new code and is not a drop-in replacement. Thus there is no need to preserve backwards behavior here, so I didn't implement that case-insensitivity.
  • The Rest map will be created on-demand; if no unexpected keys are seen and the map is nil going in, then it will still be nil afterwards.
  • The Rest map can have arbitrary value types, but if the content won't parse then you'll get an error. Sensible choices for generic usage include interface{} and json.RawMessage.

Canonical import path is: go.pennock.tech/swallowjson


Copyright © 2016-2020 Pennock Tech, LLC
Licensed per LICENSE.txt

Documentation

Overview

Package swallowjson provides a utility function for implementing the encoding/json.Unmarshaler interface's UnmarshalJSON method to decode, without discarding unknown keys. The "swallow" concept says that any keys in a JSON object which do not correspond to a known field in a (Golang) struct should not be discarded but instead put into a map.

type MyType struct {
	Foo  string                 `json:"foo"`
	Bar  int                    `json:"bar"`
	Rest map[string]interface{} `json:"-"`
}

func (mt *MyType) UnmarshalJSON(raw []byte) error {
	return swallowjson.UnmarshalWith(mt, "Rest", raw)
}

The struct field to swallow fields not explicitly named must be a map keyed by string. The type of map values is handled reliably, returning a JSON error if unsuitable. Common types to use might be `interface{}` or `json.RawMessage`.

Errors are either of type swallowjson.SwallowError or are bubbled through from the json or reflect packages.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrGivenNonStringKey       = SwallowError{/* contains filtered or unexported fields */}
	ErrMalformedJSON           = SwallowError{/* contains filtered or unexported fields */}
	ErrMissingSpilloverField   = SwallowError{/* contains filtered or unexported fields */}
	ErrNotGivenMutable         = SwallowError{/* contains filtered or unexported fields */}
	ErrNotGivenStruct          = SwallowError{/* contains filtered or unexported fields */}
	ErrNotStructHolder         = SwallowError{/* contains filtered or unexported fields */}
	ErrSpillNotRightMap        = SwallowError{/* contains filtered or unexported fields */}
	ErrUnsetableSpilloverField = SwallowError{/* contains filtered or unexported fields */}
)

These errors may be returned by UnmarshalWith.

Functions

func UnmarshalWith

func UnmarshalWith(target interface{}, spilloverName string, raw []byte) error

UnmarshalWith is used for implementing UnmarshalJSON methods to satisfy the encoding/json.Unmarshaler interface. The method becomes a one-liner returning the result of calling this function, supplying in addition to the object and input only the name of the field which should swallow unknown JSON fields.

Types

type SwallowError

type SwallowError struct {
	// contains filtered or unexported fields
}

SwallowError is the type of all errors generated within the swallowjson package. Errors will either be of this type, or bubbled through. The string representation of the error is guaranteed to start "swallowjson:".

func (SwallowError) Error

func (se SwallowError) Error() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL