A go structure for handling dynamic JSON.
- 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.
- We unmarshal the JSON into a
map[string]any
(or map[string]interface{}
as any
is an alias for interface{}
)
- 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))
- 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)