A go structure for handling dynamic JSON.

Steve Thielemann 814f756724 [Test] Added test.json and a test for it il y a 1 an
LICENSE e297efaf0f Initial commit il y a 1 an
README.md 59a6f83bc2 Pushed Repo il y a 1 an
go.mod 59a6f83bc2 Pushed Repo il y a 1 an
node.go 46f45e8f67 +NewNodeFromJSON,NewNodeFromFile,NewNodeFromStream il y a 1 an
node_test.go 814f756724 [Test] Added test.json and a test for it il y a 1 an
test.json 814f756724 [Test] Added test.json and a test for it il y a 1 an
utilities.go 59a6f83bc2 Pushed Repo il y a 1 an

README.md

node

A go structure for handling dynamic JSON.

Feature List

  • Primary Goal: Unmarshal JSON into walkable structure(s) for easier access to data. (i.e. no predefining structure(s) or unmarshaling into a map of string interface{} or any)
  • Secondary Goal: Support Marshaling into valid JSON (the order may differ) but remain technically the same JSON payload.

How it works

  1. We unmarshal the JSON into a map[string]any (or map[string]interface{} as any is an alias for interface{})
  2. Then we walk thru each element calling reflect to determine the dynamic type under run-time: *
    • Maps/Maplikes (map[string]any/map[string]interface{}) will be walked thru determining it's dynamic type *
    • Arrays/Slices/Arraylikes ([]any/[]interface{}) will be walked thru determining it's dynamic type *
    • Strings/Integers/Floats/Values (any/interface{}) will be assigned to either a named structure or a un-named structure (un-named are used when the previous depth or "parent" is determined to be Arraylike (Arrays/Slices), while named structures are used when the previous depth or "parent" is determined to be Maplike (Maps))
  3. Once the structures have been populated, all the JSON has technically been walked over, and thus the Node tree or JSON structure is now available.

* This process is recursive, it will iterate over it's elements determining their type and can possibly cause it to iterate over that.

This concept uses pointers to structures heavily for a few reasons:

  • Pointers are lighter than structures (as they are just pointing to them, so they exist in memory only once, with 1 or more pointers to them)
  • Pointers are like C++'s "Reference" (we can modify the "parent" or "children" without fear of copies and other ugly memory issues)
  • So long as there is 1 reference to the pointer, it won't be freed/forgotten (This is quite similar to all the "parent" and "children" being C++ "Smart Pointers" in that they keep a "reference count", when it's 0, then it's released)