github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/examples/gno.land/p/demo/json/node.gno (about)

     1  package json
     2  
     3  import (
     4  	"errors"
     5  	"strconv"
     6  	"strings"
     7  
     8  	"gno.land/p/demo/ufmt"
     9  )
    10  
    11  // Node represents a JSON node.
    12  type Node struct {
    13  	prev     *Node            // prev is the parent node of the current node.
    14  	next     map[string]*Node // next is the child nodes of the current node.
    15  	key      *string          // key holds the key of the current node in the parent node.
    16  	data     []byte           // byte slice of JSON data
    17  	value    interface{}      // value holds the value of the current node.
    18  	nodeType ValueType        // NodeType holds the type of the current node. (Object, Array, String, Number, Boolean, Null)
    19  	index    *int             // index holds the index of the current node in the parent array node.
    20  	borders  [2]int           // borders stores the start and end index of the current node in the data.
    21  	modified bool             // modified indicates the current node is changed or not.
    22  }
    23  
    24  // NewNode creates a new node instance with the given parent node, buffer, type, and key.
    25  func NewNode(prev *Node, b *buffer, typ ValueType, key **string) (*Node, error) {
    26  	curr := &Node{
    27  		prev:     prev,
    28  		data:     b.data,
    29  		borders:  [2]int{b.index, 0},
    30  		key:      *key,
    31  		nodeType: typ,
    32  		modified: false,
    33  	}
    34  
    35  	if typ == Object || typ == Array {
    36  		curr.next = make(map[string]*Node)
    37  	}
    38  
    39  	if prev != nil {
    40  		if prev.IsArray() {
    41  			size := len(prev.next)
    42  			curr.index = &size
    43  
    44  			prev.next[strconv.Itoa(size)] = curr
    45  		} else if prev.IsObject() {
    46  			if key == nil {
    47  				return nil, errors.New("key is required for object")
    48  			}
    49  
    50  			prev.next[**key] = curr
    51  		} else {
    52  			return nil, errors.New("invalid parent type")
    53  		}
    54  	}
    55  
    56  	return curr, nil
    57  }
    58  
    59  // load retrieves the value of the current node.
    60  func (n *Node) load() interface{} {
    61  	return n.value
    62  }
    63  
    64  // Changed checks the current node is changed or not.
    65  func (n *Node) Changed() bool {
    66  	return n.modified
    67  }
    68  
    69  // Key returns the key of the current node.
    70  func (n *Node) Key() string {
    71  	if n == nil || n.key == nil {
    72  		return ""
    73  	}
    74  
    75  	return *n.key
    76  }
    77  
    78  // HasKey checks the current node has the given key or not.
    79  func (n *Node) HasKey(key string) bool {
    80  	if n == nil {
    81  		return false
    82  	}
    83  
    84  	_, ok := n.next[key]
    85  	return ok
    86  }
    87  
    88  // GetKey returns the value of the given key from the current object node.
    89  func (n *Node) GetKey(key string) (*Node, error) {
    90  	if n == nil {
    91  		return nil, errors.New("node is nil")
    92  	}
    93  
    94  	if n.Type() != Object {
    95  		return nil, ufmt.Errorf("target node is not object type. got: %s", n.Type().String())
    96  	}
    97  
    98  	value, ok := n.next[key]
    99  	if !ok {
   100  		return nil, ufmt.Errorf("key not found: %s", key)
   101  	}
   102  
   103  	return value, nil
   104  }
   105  
   106  // MustKey returns the value of the given key from the current object node.
   107  func (n *Node) MustKey(key string) *Node {
   108  	val, err := n.GetKey(key)
   109  	if err != nil {
   110  		panic(err)
   111  	}
   112  
   113  	return val
   114  }
   115  
   116  // UniqueKeyLists traverses the current JSON nodes and collects all the unique keys.
   117  func (n *Node) UniqueKeyLists() []string {
   118  	var collectKeys func(*Node) []string
   119  	collectKeys = func(node *Node) []string {
   120  		if node == nil || !node.IsObject() {
   121  			return nil
   122  		}
   123  
   124  		result := make(map[string]bool)
   125  		for key, childNode := range node.next {
   126  			result[key] = true
   127  			childKeys := collectKeys(childNode)
   128  			for _, childKey := range childKeys {
   129  				result[childKey] = true
   130  			}
   131  		}
   132  
   133  		keys := make([]string, 0, len(result))
   134  		for key := range result {
   135  			keys = append(keys, key)
   136  		}
   137  		return keys
   138  	}
   139  
   140  	return collectKeys(n)
   141  }
   142  
   143  // Empty returns true if the current node is empty.
   144  func (n *Node) Empty() bool {
   145  	if n == nil {
   146  		return false
   147  	}
   148  
   149  	return len(n.next) == 0
   150  }
   151  
   152  // Type returns the type (ValueType) of the current node.
   153  func (n *Node) Type() ValueType {
   154  	return n.nodeType
   155  }
   156  
   157  // Value returns the value of the current node.
   158  //
   159  // Usage:
   160  //
   161  //	root := Unmarshal([]byte(`{"key": "value"}`))
   162  //	val, err := root.MustKey("key").Value()
   163  //	if err != nil {
   164  //		t.Errorf("Value returns error: %v", err)
   165  //	}
   166  //
   167  //	result: "value"
   168  func (n *Node) Value() (value interface{}, err error) {
   169  	value = n.load()
   170  
   171  	if value == nil {
   172  		switch n.nodeType {
   173  		case Null:
   174  			return nil, nil
   175  
   176  		case Number:
   177  			value, err = ParseFloatLiteral(n.source())
   178  			if err != nil {
   179  				return nil, err
   180  			}
   181  
   182  			n.value = value
   183  
   184  		case String:
   185  			var ok bool
   186  			value, ok = Unquote(n.source(), doubleQuote)
   187  			if !ok {
   188  				return "", errors.New("invalid string value")
   189  			}
   190  
   191  			n.value = value
   192  
   193  		case Boolean:
   194  			if len(n.source()) == 0 {
   195  				return nil, errors.New("empty boolean value")
   196  			}
   197  
   198  			b := n.source()[0]
   199  			value = b == 't' || b == 'T'
   200  			n.value = value
   201  
   202  		case Array:
   203  			elems := make([]*Node, len(n.next))
   204  
   205  			for _, e := range n.next {
   206  				elems[*e.index] = e
   207  			}
   208  
   209  			value = elems
   210  			n.value = value
   211  
   212  		case Object:
   213  			obj := make(map[string]*Node, len(n.next))
   214  
   215  			for k, v := range n.next {
   216  				obj[k] = v
   217  			}
   218  
   219  			value = obj
   220  			n.value = value
   221  		}
   222  	}
   223  
   224  	return value, nil
   225  }
   226  
   227  // Delete removes the current node from the parent node.
   228  //
   229  // Usage:
   230  //
   231  //	root := Unmarshal([]byte(`{"key": "value"}`))
   232  //	if err := root.MustKey("key").Delete(); err != nil {
   233  //		t.Errorf("Delete returns error: %v", err)
   234  //	}
   235  //
   236  //	result: {} (empty object)
   237  func (n *Node) Delete() error {
   238  	if n == nil {
   239  		return errors.New("can't delete nil node")
   240  	}
   241  
   242  	if n.prev == nil {
   243  		return nil
   244  	}
   245  
   246  	return n.prev.remove(n)
   247  }
   248  
   249  // Size returns the size (length) of the current array node.
   250  //
   251  // Usage:
   252  //
   253  //	root := ArrayNode("", []*Node{StringNode("", "foo"), NumberNode("", 1)})
   254  //	if root == nil {
   255  //		t.Errorf("ArrayNode returns nil")
   256  //	}
   257  //
   258  //	if root.Size() != 2 {
   259  //		t.Errorf("ArrayNode returns wrong size: %d", root.Size())
   260  //	}
   261  func (n *Node) Size() int {
   262  	if n == nil {
   263  		return 0
   264  	}
   265  
   266  	return len(n.next)
   267  }
   268  
   269  // Index returns the index of the current node in the parent array node.
   270  //
   271  // Usage:
   272  //
   273  //	root := ArrayNode("", []*Node{StringNode("", "foo"), NumberNode("", 1)})
   274  //	if root == nil {
   275  //		t.Errorf("ArrayNode returns nil")
   276  //	}
   277  //
   278  //	if root.MustIndex(1).Index() != 1 {
   279  //		t.Errorf("Index returns wrong index: %d", root.MustIndex(1).Index())
   280  //	}
   281  //
   282  // We can also use the index to the byte slice of the JSON data directly.
   283  //
   284  // Example:
   285  //
   286  //	root := Unmarshal([]byte(`["foo", 1]`))
   287  //	if root == nil {
   288  //		t.Errorf("Unmarshal returns nil")
   289  //	}
   290  //
   291  //	if string(root.MustIndex(1).source()) != "1" {
   292  //		t.Errorf("source returns wrong result: %s", root.MustIndex(1).source())
   293  //	}
   294  func (n *Node) Index() int {
   295  	if n == nil || n.index == nil {
   296  		return -1
   297  	}
   298  
   299  	return *n.index
   300  }
   301  
   302  // MustIndex returns the array element at the given index.
   303  //
   304  // If the index is negative, it returns the index is from the end of the array.
   305  // Also, it panics if the index is not found.
   306  //
   307  // check the Index method for detailed usage.
   308  func (n *Node) MustIndex(expectIdx int) *Node {
   309  	val, err := n.GetIndex(expectIdx)
   310  	if err != nil {
   311  		panic(err)
   312  	}
   313  
   314  	return val
   315  }
   316  
   317  // GetIndex returns the array element at the given index.
   318  //
   319  // if the index is negative, it returns the index is from the end of the array.
   320  func (n *Node) GetIndex(idx int) (*Node, error) {
   321  	if n == nil {
   322  		return nil, errors.New("node is nil")
   323  	}
   324  
   325  	if !n.IsArray() {
   326  		return nil, errors.New("node is not array")
   327  	}
   328  
   329  	if idx > n.Size() {
   330  		return nil, errors.New("input index exceeds the array size")
   331  	}
   332  
   333  	if idx < 0 {
   334  		idx += len(n.next)
   335  	}
   336  
   337  	child, ok := n.next[strconv.Itoa(idx)]
   338  	if !ok {
   339  		return nil, errors.New("index not found")
   340  	}
   341  
   342  	return child, nil
   343  }
   344  
   345  // DeleteIndex removes the array element at the given index.
   346  func (n *Node) DeleteIndex(idx int) error {
   347  	node, err := n.GetIndex(idx)
   348  	if err != nil {
   349  		return err
   350  	}
   351  
   352  	return n.remove(node)
   353  }
   354  
   355  // NullNode creates a new null type node.
   356  //
   357  // Usage:
   358  //
   359  //	_ := NullNode("")
   360  func NullNode(key string) *Node {
   361  	return &Node{
   362  		key:      &key,
   363  		value:    nil,
   364  		nodeType: Null,
   365  		modified: true,
   366  	}
   367  }
   368  
   369  // NumberNode creates a new number type node.
   370  //
   371  // Usage:
   372  //
   373  //	root := NumberNode("", 1)
   374  //	if root == nil {
   375  //		t.Errorf("NumberNode returns nil")
   376  //	}
   377  func NumberNode(key string, value float64) *Node {
   378  	return &Node{
   379  		key:      &key,
   380  		value:    value,
   381  		nodeType: Number,
   382  		modified: true,
   383  	}
   384  }
   385  
   386  // StringNode creates a new string type node.
   387  //
   388  // Usage:
   389  //
   390  //	root := StringNode("", "foo")
   391  //	if root == nil {
   392  //		t.Errorf("StringNode returns nil")
   393  //	}
   394  func StringNode(key string, value string) *Node {
   395  	return &Node{
   396  		key:      &key,
   397  		value:    value,
   398  		nodeType: String,
   399  		modified: true,
   400  	}
   401  }
   402  
   403  // BoolNode creates a new given boolean value node.
   404  //
   405  // Usage:
   406  //
   407  //	root := BoolNode("", true)
   408  //	if root == nil {
   409  //		t.Errorf("BoolNode returns nil")
   410  //	}
   411  func BoolNode(key string, value bool) *Node {
   412  	return &Node{
   413  		key:      &key,
   414  		value:    value,
   415  		nodeType: Boolean,
   416  		modified: true,
   417  	}
   418  }
   419  
   420  // ArrayNode creates a new array type node.
   421  //
   422  // If the given value is nil, it creates an empty array node.
   423  //
   424  // Usage:
   425  //
   426  //	root := ArrayNode("", []*Node{StringNode("", "foo"), NumberNode("", 1)})
   427  //	if root == nil {
   428  //		t.Errorf("ArrayNode returns nil")
   429  //	}
   430  func ArrayNode(key string, value []*Node) *Node {
   431  	curr := &Node{
   432  		key:      &key,
   433  		nodeType: Array,
   434  		modified: true,
   435  	}
   436  
   437  	curr.next = make(map[string]*Node, len(value))
   438  	if value != nil {
   439  		curr.value = value
   440  
   441  		for i, v := range value {
   442  			idx := i
   443  			curr.next[strconv.Itoa(i)] = v
   444  
   445  			v.prev = curr
   446  			v.index = &idx
   447  		}
   448  	}
   449  
   450  	return curr
   451  }
   452  
   453  // ObjectNode creates a new object type node.
   454  //
   455  // If the given value is nil, it creates an empty object node.
   456  //
   457  // next is a map of key and value pairs of the object.
   458  func ObjectNode(key string, value map[string]*Node) *Node {
   459  	curr := &Node{
   460  		nodeType: Object,
   461  		key:      &key,
   462  		next:     value,
   463  		modified: true,
   464  	}
   465  
   466  	if value != nil {
   467  		curr.value = value
   468  
   469  		for key, val := range value {
   470  			vkey := key
   471  			val.prev = curr
   472  			val.key = &vkey
   473  		}
   474  	} else {
   475  		curr.next = make(map[string]*Node)
   476  	}
   477  
   478  	return curr
   479  }
   480  
   481  // IsArray returns true if the current node is array type.
   482  func (n *Node) IsArray() bool {
   483  	return n.nodeType == Array
   484  }
   485  
   486  // IsObject returns true if the current node is object type.
   487  func (n *Node) IsObject() bool {
   488  	return n.nodeType == Object
   489  }
   490  
   491  // IsNull returns true if the current node is null type.
   492  func (n *Node) IsNull() bool {
   493  	return n.nodeType == Null
   494  }
   495  
   496  // IsBool returns true if the current node is boolean type.
   497  func (n *Node) IsBool() bool {
   498  	return n.nodeType == Boolean
   499  }
   500  
   501  // IsString returns true if the current node is string type.
   502  func (n *Node) IsString() bool {
   503  	return n.nodeType == String
   504  }
   505  
   506  // IsNumber returns true if the current node is number type.
   507  func (n *Node) IsNumber() bool {
   508  	return n.nodeType == Number
   509  }
   510  
   511  // ready checks the current node is ready or not.
   512  //
   513  // the meaning of ready is the current node is parsed and has a valid value.
   514  func (n *Node) ready() bool {
   515  	return n.borders[1] != 0
   516  }
   517  
   518  // source returns the source of the current node.
   519  func (n *Node) source() []byte {
   520  	if n == nil {
   521  		return nil
   522  	}
   523  
   524  	if n.ready() && !n.modified && n.data != nil {
   525  		return (n.data)[n.borders[0]:n.borders[1]]
   526  	}
   527  
   528  	return nil
   529  }
   530  
   531  // root returns the root node of the current node.
   532  func (n *Node) root() *Node {
   533  	if n == nil {
   534  		return nil
   535  	}
   536  
   537  	curr := n
   538  	for curr.prev != nil {
   539  		curr = curr.prev
   540  	}
   541  
   542  	return curr
   543  }
   544  
   545  // GetNull returns the null value if current node is null type.
   546  //
   547  // Usage:
   548  //
   549  //	root := Unmarshal([]byte("null"))
   550  //	val, err := root.GetNull()
   551  //	if err != nil {
   552  //		t.Errorf("GetNull returns error: %v", err)
   553  //	}
   554  //	if val != nil {
   555  //		t.Errorf("GetNull returns wrong result: %v", val)
   556  //	}
   557  func (n *Node) GetNull() (interface{}, error) {
   558  	if n == nil {
   559  		return nil, errors.New("node is nil")
   560  	}
   561  
   562  	if !n.IsNull() {
   563  		return nil, errors.New("node is not null")
   564  	}
   565  
   566  	return nil, nil
   567  }
   568  
   569  // MustNull returns the null value if current node is null type.
   570  //
   571  // It panics if the current node is not null type.
   572  func (n *Node) MustNull() interface{} {
   573  	v, err := n.GetNull()
   574  	if err != nil {
   575  		panic(err)
   576  	}
   577  
   578  	return v
   579  }
   580  
   581  // GetNumeric returns the numeric (int/float) value if current node is number type.
   582  //
   583  // Usage:
   584  //
   585  //	root := Unmarshal([]byte("10.5"))
   586  //	val, err := root.GetNumeric()
   587  //	if err != nil {
   588  //		t.Errorf("GetNumeric returns error: %v", err)
   589  //	}
   590  //	println(val) // 10.5
   591  func (n *Node) GetNumeric() (float64, error) {
   592  	if n == nil {
   593  		return 0, errors.New("node is nil")
   594  	}
   595  
   596  	if n.nodeType != Number {
   597  		return 0, errors.New("node is not number")
   598  	}
   599  
   600  	val, err := n.Value()
   601  	if err != nil {
   602  		return 0, err
   603  	}
   604  
   605  	v, ok := val.(float64)
   606  	if !ok {
   607  		return 0, errors.New("node is not number")
   608  	}
   609  
   610  	return v, nil
   611  }
   612  
   613  // MustNumeric returns the numeric (int/float) value if current node is number type.
   614  //
   615  // It panics if the current node is not number type.
   616  func (n *Node) MustNumeric() float64 {
   617  	v, err := n.GetNumeric()
   618  	if err != nil {
   619  		panic(err)
   620  	}
   621  
   622  	return v
   623  }
   624  
   625  // GetString returns the string value if current node is string type.
   626  //
   627  // Usage:
   628  //
   629  //	root, err := Unmarshal([]byte("foo"))
   630  //	if err != nil {
   631  //		t.Errorf("Error on Unmarshal(): %s", err)
   632  //	}
   633  //
   634  //	str, err := root.GetString()
   635  //	if err != nil {
   636  //		t.Errorf("should retrieve string value: %s", err)
   637  //	}
   638  //
   639  //	println(str) // "foo"
   640  func (n *Node) GetString() (string, error) {
   641  	if n == nil {
   642  		return "", errors.New("string node is empty")
   643  	}
   644  
   645  	if !n.IsString() {
   646  		return "", errors.New("node type is not string")
   647  	}
   648  
   649  	val, err := n.Value()
   650  	if err != nil {
   651  		return "", err
   652  	}
   653  
   654  	v, ok := val.(string)
   655  	if !ok {
   656  		return "", errors.New("node is not string")
   657  	}
   658  
   659  	return v, nil
   660  }
   661  
   662  // MustString returns the string value if current node is string type.
   663  //
   664  // It panics if the current node is not string type.
   665  func (n *Node) MustString() string {
   666  	v, err := n.GetString()
   667  	if err != nil {
   668  		panic(err)
   669  	}
   670  
   671  	return v
   672  }
   673  
   674  // GetBool returns the boolean value if current node is boolean type.
   675  //
   676  // Usage:
   677  //
   678  //	root := Unmarshal([]byte("true"))
   679  //	val, err := root.GetBool()
   680  //	if err != nil {
   681  //		t.Errorf("GetBool returns error: %v", err)
   682  //	}
   683  //	println(val) // true
   684  func (n *Node) GetBool() (bool, error) {
   685  	if n == nil {
   686  		return false, errors.New("node is nil")
   687  	}
   688  
   689  	if n.nodeType != Boolean {
   690  		return false, errors.New("node is not boolean")
   691  	}
   692  
   693  	val, err := n.Value()
   694  	if err != nil {
   695  		return false, err
   696  	}
   697  
   698  	v, ok := val.(bool)
   699  	if !ok {
   700  		return false, errors.New("node is not boolean")
   701  	}
   702  
   703  	return v, nil
   704  }
   705  
   706  // MustBool returns the boolean value if current node is boolean type.
   707  //
   708  // It panics if the current node is not boolean type.
   709  func (n *Node) MustBool() bool {
   710  	v, err := n.GetBool()
   711  	if err != nil {
   712  		panic(err)
   713  	}
   714  
   715  	return v
   716  }
   717  
   718  // GetArray returns the array value if current node is array type.
   719  //
   720  // Usage:
   721  //
   722  //		root := Must(Unmarshal([]byte(`["foo", 1]`)))
   723  //		arr, err := root.GetArray()
   724  //		if err != nil {
   725  //			t.Errorf("GetArray returns error: %v", err)
   726  //		}
   727  //
   728  //		for _, val := range arr {
   729  //			println(val)
   730  //		}
   731  //
   732  //	 result: "foo", 1
   733  func (n *Node) GetArray() ([]*Node, error) {
   734  	if n == nil {
   735  		return nil, errors.New("node is nil")
   736  	}
   737  
   738  	if n.nodeType != Array {
   739  		return nil, errors.New("node is not array")
   740  	}
   741  
   742  	val, err := n.Value()
   743  	if err != nil {
   744  		return nil, err
   745  	}
   746  
   747  	v, ok := val.([]*Node)
   748  	if !ok {
   749  		return nil, errors.New("node is not array")
   750  	}
   751  
   752  	return v, nil
   753  }
   754  
   755  // MustArray returns the array value if current node is array type.
   756  //
   757  // It panics if the current node is not array type.
   758  func (n *Node) MustArray() []*Node {
   759  	v, err := n.GetArray()
   760  	if err != nil {
   761  		panic(err)
   762  	}
   763  
   764  	return v
   765  }
   766  
   767  // AppendArray appends the given values to the current array node.
   768  //
   769  // If the current node is not array type, it returns an error.
   770  //
   771  // Example 1:
   772  //
   773  //	root := Must(Unmarshal([]byte(`[{"foo":"bar"}]`)))
   774  //	if err := root.AppendArray(NullNode("")); err != nil {
   775  //		t.Errorf("should not return error: %s", err)
   776  //	}
   777  //
   778  //	result: [{"foo":"bar"}, null]
   779  //
   780  // Example 2:
   781  //
   782  //	root := Must(Unmarshal([]byte(`["bar", "baz"]`)))
   783  //	err := root.AppendArray(NumberNode("", 1), StringNode("", "foo"))
   784  //	if err != nil {
   785  //		t.Errorf("AppendArray returns error: %v", err)
   786  //	 }
   787  //
   788  //	result: ["bar", "baz", 1, "foo"]
   789  func (n *Node) AppendArray(value ...*Node) error {
   790  	if !n.IsArray() {
   791  		return errors.New("can't append value to non-array node")
   792  	}
   793  
   794  	for _, val := range value {
   795  		if err := n.append(nil, val); err != nil {
   796  			return err
   797  		}
   798  	}
   799  
   800  	n.mark()
   801  	return nil
   802  }
   803  
   804  // ArrayEach executes the callback for each element in the JSON array.
   805  //
   806  // Usage:
   807  //
   808  //	jsonArrayNode.ArrayEach(func(i int, valueNode *Node) {
   809  //	    ufmt.Println(i, valueNode)
   810  //	})
   811  func (n *Node) ArrayEach(callback func(i int, target *Node)) {
   812  	if n == nil || !n.IsArray() {
   813  		return
   814  	}
   815  
   816  	for idx := 0; idx < len(n.next); idx++ {
   817  		element, err := n.GetIndex(idx)
   818  		if err != nil {
   819  			continue
   820  		}
   821  
   822  		callback(idx, element)
   823  	}
   824  }
   825  
   826  // GetObject returns the object value if current node is object type.
   827  //
   828  // Usage:
   829  //
   830  //	root := Must(Unmarshal([]byte(`{"key": "value"}`)))
   831  //	obj, err := root.GetObject()
   832  //	if err != nil {
   833  //		t.Errorf("GetObject returns error: %v", err)
   834  //	}
   835  //
   836  //	result: map[string]*Node{"key": StringNode("key", "value")}
   837  func (n *Node) GetObject() (map[string]*Node, error) {
   838  	if n == nil {
   839  		return nil, errors.New("node is nil")
   840  	}
   841  
   842  	if !n.IsObject() {
   843  		return nil, errors.New("node is not object")
   844  	}
   845  
   846  	val, err := n.Value()
   847  	if err != nil {
   848  		return nil, err
   849  	}
   850  
   851  	v, ok := val.(map[string]*Node)
   852  	if !ok {
   853  		return nil, errors.New("node is not object")
   854  	}
   855  
   856  	return v, nil
   857  }
   858  
   859  // MustObject returns the object value if current node is object type.
   860  //
   861  // It panics if the current node is not object type.
   862  func (n *Node) MustObject() map[string]*Node {
   863  	v, err := n.GetObject()
   864  	if err != nil {
   865  		panic(err)
   866  	}
   867  
   868  	return v
   869  }
   870  
   871  // AppendObject appends the given key and value to the current object node.
   872  //
   873  // If the current node is not object type, it returns an error.
   874  func (n *Node) AppendObject(key string, value *Node) error {
   875  	if !n.IsObject() {
   876  		return errors.New("can't append value to non-object node")
   877  	}
   878  
   879  	if err := n.append(&key, value); err != nil {
   880  		return err
   881  	}
   882  
   883  	n.mark()
   884  	return nil
   885  }
   886  
   887  // ObjectEach executes the callback for each key-value pair in the JSON object.
   888  //
   889  // Usage:
   890  //
   891  //	jsonObjectNode.ObjectEach(func(key string, valueNode *Node) {
   892  //	    ufmt.Println(key, valueNode)
   893  //	})
   894  func (n *Node) ObjectEach(callback func(key string, value *Node)) {
   895  	if n == nil || !n.IsObject() {
   896  		return
   897  	}
   898  
   899  	for key, child := range n.next {
   900  		callback(key, child)
   901  	}
   902  }
   903  
   904  // String converts the node to a string representation.
   905  func (n *Node) String() string {
   906  	if n == nil {
   907  		return ""
   908  	}
   909  
   910  	if n.ready() && !n.modified {
   911  		return string(n.source())
   912  	}
   913  
   914  	val, err := Marshal(n)
   915  	if err != nil {
   916  		return "error: " + err.Error()
   917  	}
   918  
   919  	return string(val)
   920  }
   921  
   922  // Path builds the path of the current node.
   923  //
   924  // For example:
   925  //
   926  //	{ "key": { "sub": [ "val1", "val2" ] }}
   927  //
   928  // The path of "val2" is: $.key.sub[1]
   929  func (n *Node) Path() string {
   930  	if n == nil {
   931  		return ""
   932  	}
   933  
   934  	var sb strings.Builder
   935  
   936  	if n.prev == nil {
   937  		sb.WriteString("$")
   938  	} else {
   939  		sb.WriteString(n.prev.Path())
   940  
   941  		if n.key != nil {
   942  			sb.WriteString("['" + n.Key() + "']")
   943  		} else {
   944  			sb.WriteString("[" + strconv.Itoa(n.Index()) + "]")
   945  		}
   946  	}
   947  
   948  	return sb.String()
   949  }
   950  
   951  // mark marks the current node as modified.
   952  func (n *Node) mark() {
   953  	node := n
   954  	for node != nil && !node.modified {
   955  		node.modified = true
   956  		node = node.prev
   957  	}
   958  }
   959  
   960  // isContainer checks the current node type is array or object.
   961  func (n *Node) isContainer() bool {
   962  	return n.IsArray() || n.IsObject()
   963  }
   964  
   965  // remove removes the value from the current container type node.
   966  func (n *Node) remove(v *Node) error {
   967  	if !n.isContainer() {
   968  		return ufmt.Errorf(
   969  			"can't remove value from non-array or non-object node. got=%s",
   970  			n.Type().String(),
   971  		)
   972  	}
   973  
   974  	if v.prev != n {
   975  		return errors.New("invalid parent node")
   976  	}
   977  
   978  	n.mark()
   979  	if n.IsArray() {
   980  		delete(n.next, strconv.Itoa(*v.index))
   981  		n.dropIndex(*v.index)
   982  	} else {
   983  		delete(n.next, *v.key)
   984  	}
   985  
   986  	v.prev = nil
   987  	return nil
   988  }
   989  
   990  // dropIndex rebase the index of current array node values.
   991  func (n *Node) dropIndex(idx int) {
   992  	for i := idx + 1; i <= len(n.next); i++ {
   993  		prv := i - 1
   994  		if curr, ok := n.next[strconv.Itoa(i)]; ok {
   995  			curr.index = &prv
   996  			n.next[strconv.Itoa(prv)] = curr
   997  		}
   998  
   999  		delete(n.next, strconv.Itoa(i))
  1000  	}
  1001  }
  1002  
  1003  // append is a helper function to append the given value to the current container type node.
  1004  func (n *Node) append(key *string, val *Node) error {
  1005  	if n.isSameOrParentNode(val) {
  1006  		return errors.New("can't append same or parent node")
  1007  	}
  1008  
  1009  	if val.prev != nil {
  1010  		if err := val.prev.remove(val); err != nil {
  1011  			return err
  1012  		}
  1013  	}
  1014  
  1015  	val.prev = n
  1016  	val.key = key
  1017  
  1018  	if key == nil {
  1019  		size := len(n.next)
  1020  		val.index = &size
  1021  		n.next[strconv.Itoa(size)] = val
  1022  	} else {
  1023  		if old, ok := n.next[*key]; ok {
  1024  			if err := n.remove(old); err != nil {
  1025  				return err
  1026  			}
  1027  		}
  1028  		n.next[*key] = val
  1029  	}
  1030  
  1031  	return nil
  1032  }
  1033  
  1034  func (n *Node) isSameOrParentNode(nd *Node) bool {
  1035  	return n == nd || n.isParentNode(nd)
  1036  }
  1037  
  1038  func (n *Node) isParentNode(nd *Node) bool {
  1039  	if n == nil {
  1040  		return false
  1041  	}
  1042  
  1043  	for curr := nd.prev; curr != nil; curr = curr.prev {
  1044  		if curr == n {
  1045  			return true
  1046  		}
  1047  	}
  1048  
  1049  	return false
  1050  }
  1051  
  1052  // cptrs returns the pointer of the given string value.
  1053  func cptrs(cpy *string) *string {
  1054  	if cpy == nil {
  1055  		return nil
  1056  	}
  1057  
  1058  	val := *cpy
  1059  
  1060  	return &val
  1061  }
  1062  
  1063  // cptri returns the pointer of the given integer value.
  1064  func cptri(i *int) *int {
  1065  	if i == nil {
  1066  		return nil
  1067  	}
  1068  
  1069  	val := *i
  1070  	return &val
  1071  }
  1072  
  1073  // Must panics if the given node is not fulfilled the expectation.
  1074  // Usage:
  1075  //
  1076  //	node := Must(Unmarshal([]byte(`{"key": "value"}`))
  1077  func Must(root *Node, expect error) *Node {
  1078  	if expect != nil {
  1079  		panic(expect)
  1080  	}
  1081  
  1082  	return root
  1083  }