node.go 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  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. // New kid, with name, and recurse
  217. kid := n.NewKidWithName(k)
  218. kid.from(v)
  219. default:
  220. // New kid, with name, and data
  221. n.NewKidWithNameAndData(k, v)
  222. }
  223. }
  224. case reflect.Array, reflect.Slice:
  225. // Ok, values
  226. // no name (use index), value if not a map, array, slice is data
  227. a := A.([]any)
  228. for idx, v := range a {
  229. switch reflect.TypeOf(v).Kind() {
  230. case reflect.Map, reflect.Array, reflect.Slice:
  231. kid := n.NewKidWithName(fmt.Sprintf("%d", idx))
  232. kid.from(v)
  233. default:
  234. n.NewKidWithNameAndData(fmt.Sprintf("%d", idx), v)
  235. }
  236. }
  237. default:
  238. // Ok it's just a single value (most likely)
  239. n.Data(A)
  240. }
  241. }
  242. func (n *Node) ToMap() any {
  243. if len(n.Name()) != 0 && n.Len() != 0 { // Name + Children
  244. if n.IsMapLike() {
  245. // Map
  246. m := map[string]any{}
  247. for i, kid := range n.children {
  248. if len(kid.Name()) != 0 {
  249. m[kid.Name()] = kid.ToMap()
  250. } else {
  251. m[fmt.Sprint(i)] = kid.ToMap()
  252. }
  253. }
  254. if n.Depth() != 0 {
  255. return m
  256. } else {
  257. return map[string]any{
  258. n.Name(): m,
  259. }
  260. }
  261. } else {
  262. // Array
  263. a := []any{}
  264. for _, kid := range n.children {
  265. a = append(a, kid.ToMap())
  266. }
  267. if n.Depth() != 0 {
  268. return a
  269. } else {
  270. return map[string]any{
  271. n.Name(): a,
  272. }
  273. }
  274. }
  275. } else if len(n.Name()) == 0 && n.Len() != 0 { // No Name + Children
  276. if n.IsMapLike() {
  277. // Map
  278. m := map[string]any{}
  279. for i, kid := range n.children {
  280. if len(kid.Name()) != 0 {
  281. m[kid.Name()] = kid.ToMap()
  282. } else {
  283. m[fmt.Sprint(i)] = kid.ToMap()
  284. }
  285. }
  286. return m
  287. } else {
  288. // Array
  289. a := []any{}
  290. for _, kid := range n.children {
  291. a = append(a, kid.ToMap())
  292. }
  293. if n.Depth() != 0 {
  294. return a
  295. } else {
  296. return map[string]any{
  297. fmt.Sprint(n.Index()): a,
  298. }
  299. }
  300. }
  301. } else if n.Data() != nil {
  302. if n.Depth() != 0 || len(n.Name()) == 0 {
  303. return n.Data()
  304. } else {
  305. return map[string]any{
  306. n.Name(): n.Data(),
  307. }
  308. }
  309. }
  310. return nil
  311. }
  312. // Marshals the results from ToMap
  313. func (n *Node) MarshalJSON() ([]byte, error) {
  314. return json.Marshal(n.ToMap())
  315. }
  316. // Unmarshal function
  317. func (n *Node) UnmarshalJSON(pay []byte) error {
  318. var m map[string]any
  319. err := json.Unmarshal(pay, &m)
  320. if err != nil {
  321. return err
  322. }
  323. n.Destroy()
  324. // In this case, the struct isn't in a invalid state, it's just a reset
  325. n.from(m)
  326. return nil
  327. }