node.go 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. package node
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "io"
  6. "os"
  7. "reflect"
  8. "strings"
  9. )
  10. type Node struct {
  11. name string
  12. data any
  13. parent *Node
  14. children []*Node
  15. }
  16. func NewNode() *Node {
  17. return &Node{}
  18. }
  19. func NewNodeWithName(name string) *Node {
  20. return &Node{name: name}
  21. }
  22. func NewNodeWithData(data any) *Node {
  23. return &Node{data: data}
  24. }
  25. func NewNodeWithNameAndData(name string, data any) *Node {
  26. return &Node{name: name, data: data}
  27. }
  28. func NewNodeWithDataAndName(data any, name string) *Node {
  29. return &Node{name: name, data: data}
  30. }
  31. func NewNodeFromJSON(data []byte) (*Node, error) {
  32. n := NewNode()
  33. err := json.Unmarshal(data, &n)
  34. if err != nil {
  35. return nil, err
  36. }
  37. return n, nil
  38. }
  39. func NewNodeFromFile(name string) (*Node, error) {
  40. pay, err := os.ReadFile(name)
  41. if err != nil {
  42. return nil, err
  43. }
  44. return NewNodeFromJSON(pay)
  45. }
  46. func NewNodeFromStream(r io.Reader) (*Node, error) {
  47. doc := json.NewDecoder(r)
  48. root := NewNode()
  49. work := root
  50. var (
  51. depth int = 0
  52. maplike bool = false
  53. lastToken string
  54. )
  55. for {
  56. t, err := doc.Token()
  57. if err == io.EOF {
  58. break
  59. }
  60. if err != nil {
  61. return nil, err
  62. }
  63. delim, ok := t.(json.Delim)
  64. if ok {
  65. if rune(delim) == '{' || rune(delim) == '[' {
  66. work = work.NewKid()
  67. depth++
  68. if rune(delim) == '{' {
  69. maplike = true
  70. } else {
  71. maplike = false
  72. }
  73. } else if rune(delim) == '}' || rune(delim) == ']' {
  74. if work.Parent() != nil {
  75. depth--
  76. work = work.Parent()
  77. maplike = work.IsMapLike()
  78. }
  79. }
  80. } else {
  81. text := fmt.Sprintf("%v", t)
  82. if lastToken == "" {
  83. lastToken = text
  84. } else {
  85. lastToken = ""
  86. }
  87. fmt.Printf("%s%s", strings.Repeat(" ", depth), text)
  88. if doc.More() {
  89. fmt.Printf(" (more)")
  90. }
  91. fmt.Printf("\n")
  92. if work.Name() == "" && maplike {
  93. work.Name(text)
  94. } else if maplike {
  95. if !doc.More() {
  96. work.Data(t.(any))
  97. } else {
  98. work.NewKidWithData(t.(any))
  99. }
  100. } else if !maplike {
  101. work.NewKidWithData(t.(any))
  102. }
  103. }
  104. }
  105. return root, nil
  106. }
  107. func (n *Node) Name(name ...string) string {
  108. if len(name) != 0 {
  109. n.name = name[0]
  110. }
  111. return n.name
  112. }
  113. func (n *Node) Data(data ...any) any {
  114. if len(data) != 0 {
  115. n.data = data[0]
  116. }
  117. return n.data
  118. }
  119. func (n *Node) Len() int {
  120. return len(n.children)
  121. }
  122. func (n *Node) Parent(parent ...*Node) *Node {
  123. if len(parent) != 0 {
  124. n.parent = parent[0]
  125. }
  126. return n.parent
  127. }
  128. func (n *Node) Root() *Node {
  129. if n.Parent() == nil {
  130. return n
  131. }
  132. at := n.Parent()
  133. for at.Parent() != nil {
  134. at = at.Parent()
  135. }
  136. return at
  137. }
  138. func (n *Node) Depth() int {
  139. if n.Parent() == nil {
  140. return 0
  141. }
  142. var (
  143. depth int = 1
  144. at *Node = n.Parent()
  145. )
  146. for at.Parent() != nil {
  147. depth++
  148. at = at.Parent()
  149. }
  150. return depth
  151. }
  152. func (n *Node) Kids() []*Node {
  153. return n.children
  154. }
  155. func (n *Node) AddKid(kid *Node) bool {
  156. for _, k := range n.children {
  157. if k == kid {
  158. return false
  159. }
  160. }
  161. kid.Parent(n)
  162. n.children = append(n.children, kid)
  163. return true
  164. }
  165. func (n *Node) NewKid() *Node {
  166. k := &Node{}
  167. n.AddKid(k)
  168. return k
  169. }
  170. func (n *Node) NewKidWithName(name string) *Node {
  171. k := n.NewKid()
  172. k.Name(name)
  173. return k
  174. }
  175. func (n *Node) NewKidWithData(data any) *Node {
  176. k := n.NewKid()
  177. k.Data(data)
  178. return k
  179. }
  180. func (n *Node) NewKidWithNameAndData(name string, data any) *Node {
  181. k := n.NewKid()
  182. k.Name(name)
  183. k.Data(data)
  184. return k
  185. }
  186. func (n *Node) NewKidWithDataAndName(data any, name string) *Node {
  187. k := n.NewKid()
  188. k.Name(name)
  189. k.Data(data)
  190. return k
  191. }
  192. func (n *Node) Index() int {
  193. if n.Parent() == nil { // There is no parent, so it's not known
  194. return -1
  195. }
  196. // Iterate thru the children of the parent to find ourselves
  197. for i, kid := range n.Parent().Kids() {
  198. if kid == n {
  199. return i
  200. }
  201. }
  202. // Ok we for some reason are not in that list, so it's not known
  203. return -1
  204. }
  205. func (n *Node) Kid(index int) *Node {
  206. if n == nil || index > n.Len() || index < 0 {
  207. return nil
  208. }
  209. return n.children[index]
  210. }
  211. func (n *Node) KidByName(name string, recurse ...bool) *Node {
  212. for _, kid := range n.children {
  213. if kid.name == name {
  214. return kid
  215. }
  216. }
  217. if len(recurse) != 0 {
  218. if recurse[0] {
  219. for _, kid := range n.children {
  220. r := kid.KidByName(name, recurse...)
  221. if r != nil {
  222. return r
  223. }
  224. }
  225. }
  226. }
  227. return nil
  228. }
  229. func (n *Node) RemoveKid(index int) bool {
  230. if index > n.Len() || index < 0 {
  231. return false
  232. }
  233. n.children[index].Parent(nil)
  234. _, ok := arrayDelete(&n.children, index)
  235. return ok
  236. }
  237. func (n *Node) RemoveAllKids() {
  238. for _, kid := range n.children {
  239. kid.Parent(nil)
  240. }
  241. n.children = []*Node{}
  242. }
  243. func (n *Node) Detach() bool {
  244. if n.Parent() != nil {
  245. return false
  246. }
  247. index := n.Index()
  248. if index == -1 {
  249. return false
  250. }
  251. return n.Parent().RemoveKid(index)
  252. }
  253. func (n *Node) Destroy() {
  254. if n.Parent() != nil {
  255. n.Detach()
  256. }
  257. n.Data(nil)
  258. n.Name("")
  259. for _, kid := range n.children {
  260. kid.Destroy()
  261. }
  262. }
  263. // Checks if the children of this node are better represented as a map or an array
  264. //
  265. // This is determined by:
  266. //
  267. // * Totaling number of children without names
  268. //
  269. // * Comparing the percent of children without names to total children (if less than 50% use a map, if more than 50% use an array)
  270. func (n *Node) IsMapLike() bool {
  271. if n.Len() == 0 {
  272. return false
  273. }
  274. var (
  275. total int = n.Len() // number of children
  276. noname int = 0 // number of children with no name
  277. )
  278. for _, kid := range n.Kids() {
  279. if len(kid.Name()) == 0 { // When it has no name it's not map-like
  280. noname += 1
  281. }
  282. }
  283. // Form a percent of no name children and compare it to less than 50%
  284. return int((float32(noname)/float32(total))*100.0) <= 50
  285. }
  286. func (n *Node) from(A any) {
  287. switch reflect.TypeOf(A).Kind() {
  288. case reflect.Map:
  289. // Ok, key, value
  290. // key == name, value if not a map, array, slice is data
  291. m := A.(map[string]any)
  292. for k, v := range m {
  293. switch reflect.TypeOf(v).Kind() {
  294. case reflect.Map, reflect.Array, reflect.Slice:
  295. if n.Depth() != 0 || len(m) > 1 {
  296. // New kid, with name, and recurse
  297. kid := n.NewKidWithName(k)
  298. kid.from(v)
  299. } else {
  300. // This is within the "root" node
  301. n.Name(k)
  302. n.from(v)
  303. }
  304. default:
  305. // New kid, with name, and data
  306. n.NewKidWithNameAndData(k, v)
  307. }
  308. }
  309. case reflect.Array, reflect.Slice:
  310. // Ok, values
  311. // no name (use index), value if not a map, array, slice is data
  312. a := A.([]any)
  313. for idx, v := range a {
  314. switch reflect.TypeOf(v).Kind() {
  315. case reflect.Map, reflect.Array, reflect.Slice:
  316. if n.Depth() != 0 || len(a) > 1 {
  317. kid := n.NewKidWithName(fmt.Sprintf("%d", idx))
  318. kid.from(v)
  319. } else {
  320. n.Name(fmt.Sprintf("%d", idx))
  321. n.from(v)
  322. }
  323. default:
  324. n.NewKidWithNameAndData(fmt.Sprintf("%d", idx), v)
  325. }
  326. }
  327. default:
  328. // Ok it's just a single value (most likely)
  329. n.Data(A)
  330. }
  331. }
  332. func (n *Node) ToMap() any {
  333. if len(n.Name()) != 0 && n.Len() != 0 { // Name + Children
  334. if n.IsMapLike() {
  335. // Map
  336. m := map[string]any{}
  337. for i, kid := range n.children {
  338. if len(kid.Name()) != 0 {
  339. m[kid.Name()] = kid.ToMap()
  340. } else {
  341. m[fmt.Sprint(i)] = kid.ToMap()
  342. }
  343. }
  344. if n.Depth() != 0 {
  345. return m
  346. } else {
  347. return map[string]any{
  348. n.Name(): m,
  349. }
  350. }
  351. } else {
  352. // Array
  353. a := []any{}
  354. for _, kid := range n.children {
  355. a = append(a, kid.ToMap())
  356. }
  357. if n.Depth() != 0 {
  358. return a
  359. } else {
  360. return map[string]any{
  361. n.Name(): a,
  362. }
  363. }
  364. }
  365. } else if len(n.Name()) == 0 && n.Len() != 0 { // No Name + Children
  366. if n.IsMapLike() {
  367. // Map
  368. m := map[string]any{}
  369. for i, kid := range n.children {
  370. if len(kid.Name()) != 0 {
  371. m[kid.Name()] = kid.ToMap()
  372. } else {
  373. m[fmt.Sprint(i)] = kid.ToMap()
  374. }
  375. }
  376. return m
  377. } else {
  378. // Array
  379. a := []any{}
  380. for _, kid := range n.children {
  381. a = append(a, kid.ToMap())
  382. }
  383. if n.Depth() != 0 {
  384. return a
  385. } else {
  386. return map[string]any{
  387. fmt.Sprint(n.Index()): a,
  388. }
  389. }
  390. }
  391. } else if n.Data() != nil {
  392. if n.Depth() != 0 || len(n.Name()) == 0 {
  393. return n.Data()
  394. } else {
  395. return map[string]any{
  396. n.Name(): n.Data(),
  397. }
  398. }
  399. }
  400. return nil
  401. }
  402. // Marshals the results from ToMap
  403. func (n *Node) MarshalJSON() ([]byte, error) {
  404. return json.Marshal(n.ToMap())
  405. }
  406. // Unmarshal function
  407. func (n *Node) UnmarshalJSON(pay []byte) error {
  408. var m map[string]any
  409. err := json.Unmarshal(pay, &m)
  410. if err != nil {
  411. return err
  412. }
  413. n.Destroy()
  414. // In this case, the struct isn't in a invalid state, it's just a reset
  415. n.from(m)
  416. return nil
  417. }