Categorygithub.com/x1unix/jsonreflect
modulepackage
0.0.1
Repository: https://github.com/x1unix/jsonreflect.git
Documentation: pkg.go.dev

# README

jsonreflect

GoDoc

Package provides reflection features for JSON values.

Goal

This package provides reflection features to JSON, which allows working with JSON structure in reflect package manner.

Package might be useful in cases when unmarshal logic depends on source data structure like:

  • Object field type may vary (field can be array or object).
  • Object may contain fields stored in separate properties with same prefix, instead of array.
  • Object structure is polymorphic.

And for other cases of bad JSON structure design.

Examples

Processing unknown values

For instance, there is an object which only have a small subset of known fields and there is a need to separate known values from orphans for future processing.

Example below shows how jsonreflect allows collecting all unknown fields on value unmarshal.

package main

import (
    "fmt"
	
    "github.com/x1unix/jsonreflect"
)

type GenericResponse struct {
    // Known fields
    Status int      `json:"status"`
    Payload []byte  `json:"payload"`
    
    // Container for unknown fields.
    // Also, *json.Value can be used to get values as JSON object.
    Orphan map[string]interface{}  `json:"..."`
}

func unmarshalGenericResponse(data []byte) error {
    rsp := new(GenericResponse)
    if err := jsonreflect.Unmarshal(data, rsp); err != nil {
        return err
    }
    
    // Process orphan fields
    fmt.Println(rsp.Orphan)
    return nil
}

Corrupted object

For instance, we have an JSON response from some service with specified structure, but sometimes service returns response with different structure when internal error occurs.

Normal response

{
  "STATUS": [
    {
      "STATUS": "S",
      "When": 1609265946,
      "Code": 9,
      "Msg": "3 ASC(s)"
    }
  ],
  "DATA": ["some actual data..."]
}

Abnornal response:

{
  "STATUS": "E",
  "When": 1609267826,
  "Code": 14,
  "Msg": "invalid cmd",
  "Description": "cgminer v1.3"
}

In normal cases, STATUS is an array but sometimes it might be a regular object. Let's mitigate this issue.

Example

package main

import (
	"fmt"
	
	"github.com/x1unix/jsonreflect"
)

type Status struct {
	// status struct from json above
}

// checkStatus function checks if one of statuses contains error
func checkStatus(statuses []Status) error

// checkResponseError checks if response has an error
func checkResponseError(resp []byte) error {
    // Check if response has error
    value, err := jsonreflect.ValueOf(resp)
    if err != nil {
        // Invalid json
        return err
    }
    
    // cast response to object
    obj, err := jsonreflect.ToObject(value)
    if err != nil {
    	// handle invalid response
    	return fmt.Errorf("unexpected response: %v", value.Interface())
    }
    
    statusVal := obj.Items["STATUS"]
    
    // wrap status with array
    if jsonreflect.TypeOf(statusVal) != jsonreflect.TypeArray {
    	statusVal = jsonreflect.NewArray(statusVal)
    }
    
    // unmarshal value to struct and do our stuff
    var statuses []Status
    if err = jsonreflect.UnmarshalValue(statusVal, &statuses); err != nil {
    	return err
    }
    
    return checkStatus(statuses)
}

# Functions

MarshalValue returns the JSON encoding of passed jsonreflect.Value Accepts optional argument which allows to specify indent.
NewArray creates a new array of values.
No description provided by the author
No description provided by the author
NewParser creates a new parser instance.
NewParserFromReader reads data from passed reader and returns reader instance.
No description provided by the author
ToArray casts generic value to jsonreflect.Array.
ToNumber casts generic value to jsonreflect.Number.
ToObject casts generic value to jsonreflect.Object.
TypeOf returns value type.
Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v.
UnmarshalValue maps JSON value to passed value.
ValueOf parses the JSON-encoded data and returns a document structure.

# Constants

TypeArray is array value type.
TypeBoolean is boolean value type.
TypeNull is null value type.
TypeNumber is number value type.
TypeObject is object value type.
TypeString is string value type.
TypeUnknown is invalid value type.

# Variables

DangerouslySetPrivateFields allows unmarshaler to modify private fields which have `json` tag.
ErrNotStringable means that value cannot be converted to string representation.
NoStrict disables unmarshal strict mode.

# Structs

Array represents JSON items list.
Boolean is boolean value.
No description provided by the author
MarshalOptions contains additional marshal options.
Null is JSON null value.
Number represents json float64 number value.
Object represents key-value pair of object field and value.
No description provided by the author
Parser is JSON parser.
No description provided by the author
String represents JSON string.

# Interfaces

Unmarshaler is the interface implemented by types that can unmarshal a JSON value description of themselves.
Value is abstract JSON document value.

# Type aliases

No description provided by the author
Type represents value type.
UnmarshalOption is unmarshal option.