node.go 6.9 KB

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