PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/p/onbloc/json/v0

Package
Open in gnoweb ↗

Overview

Kind
Pure package
Name
v0
Namespace
onbloc / json
Files
24 (README)(gnomod.toml)
Exported functions
n/a — not supported for pure packages by the node (vm/qfuncs)
Module
gno.land/p/onbloc/json/v0
gno
0.9

Files (24)

  • README.mdmarkdown
  • gnomod.tomltoml
  • buffer.gnogno
  • builder.gnogno
  • decode.gnogno
  • encode.gnogno
  • errors.gnogno
  • escape.gnogno
  • indent.gnogno
  • internal.gnogno
  • node.gnogno
  • parser.gnogno
  • path.gnogno
  • token.gnogno
  • buffer_test.gnogno
  • builder_test.gnogno
  • decode_test.gnogno
  • encode_test.gnogno
  • escape_test.gnogno
  • indent_test.gnogno
  • node_test.gnogno
  • parser_test.gnogno
  • path_test.gnogno
  • LICENSEother
  • node.gnogno
    1package json23import (4	"errors"5	"strconv"6	"strings"78

    Functions

    not supported for pure packages by the node (vm/qfuncs)

    Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.

    "gno.land/p/nt/ufmt/v0"
    9)
    10
    11// Node represents a JSON node.
    12type 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 any // 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.
    25func 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, errKeyRequired
    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.
    60func (n *Node) load() any {
    61 return n.value
    62}
    63
    64// Changed checks the current node is changed or not.
    65func (n *Node) Changed() bool {
    66 return n.modified
    67}
    68
    69// Key returns the key of the current node.
    70func (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.
    79func (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.
    89func (n *Node) GetKey(key string) (*Node, error) {
    90 if n == nil {
    91 return nil, errNilNode
    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.
    107func (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.
    117func (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.
    144func (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.
    153func (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"
    168func (n *Node) Value() (value any, 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 = strconv.ParseFloat(string(n.source()), 64)
    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 "", errInvalidStringValue
    189 }
    190
    191 n.value = value
    192
    193 case Boolean:
    194 if len(n.source()) == 0 {
    195 return nil, errEmptyBooleanNode
    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)
    237func (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// }
    261func (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// }
    294func (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.
    308func (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.
    320func (n *Node) GetIndex(idx int) (*Node, error) {
    321 if n == nil {
    322 return nil, errNilNode
    323 }
    324
    325 if !n.IsArray() {
    326 return nil, errNotArrayNode
    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, errIndexNotFound
    340 }
    341
    342 return child, nil
    343}
    344
    345// DeleteIndex removes the array element at the given index.
    346func (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("")
    360func 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// }
    377func 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// }
    394func 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// }
    411func 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// }
    430func 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.
    458func 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.
    482func (n *Node) IsArray() bool {
    483 return n.nodeType == Array
    484}
    485
    486// IsObject returns true if the current node is object type.
    487func (n *Node) IsObject() bool {
    488 return n.nodeType == Object
    489}
    490
    491// IsNull returns true if the current node is null type.
    492func (n *Node) IsNull() bool {
    493 return n.nodeType == Null
    494}
    495
    496// IsBool returns true if the current node is boolean type.
    497func (n *Node) IsBool() bool {
    498 return n.nodeType == Boolean
    499}
    500
    501// IsString returns true if the current node is string type.
    502func (n *Node) IsString() bool {
    503 return n.nodeType == String
    504}
    505
    506// IsNumber returns true if the current node is number type.
    507func (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.
    514func (n *Node) ready() bool {
    515 return n.borders[1] != 0
    516}
    517
    518// source returns the source of the current node.
    519func (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.
    532func (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// }
    557func (n *Node) GetNull() (any, error) {
    558 if n == nil {
    559 return nil, errNilNode
    560 }
    561
    562 if !n.IsNull() {
    563 return nil, errNotNullNode
    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.
    572func (n *Node) MustNull() any {
    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
    591func (n *Node) GetNumeric() (float64, error) {
    592 if n == nil {
    593 return 0, errNilNode
    594 }
    595
    596 if n.nodeType != Number {
    597 return 0, errNotNumberNode
    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, errNotNumberNode
    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.
    616func (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"
    640func (n *Node) GetString() (string, error) {
    641 if n == nil {
    642 return "", errEmptyStringNode
    643 }
    644
    645 if !n.IsString() {
    646 return "", errNotStringNode
    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 "", errNotStringNode
    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.
    665func (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
    684func (n *Node) GetBool() (bool, error) {
    685 if n == nil {
    686 return false, errNilNode
    687 }
    688
    689 if n.nodeType != Boolean {
    690 return false, errNotBoolNode
    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, errNotBoolNode
    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.
    709func (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
    733func (n *Node) GetArray() ([]*Node, error) {
    734 if n == nil {
    735 return nil, errNilNode
    736 }
    737
    738 if n.nodeType != Array {
    739 return nil, errNotArrayNode
    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, errNotArrayNode
    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.
    758func (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"]
    789func (n *Node) AppendArray(value ...*Node) error {
    790 if !n.IsArray() {
    791 return errInvalidAppend
    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// })
    811func (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")}
    837func (n *Node) GetObject() (map[string]*Node, error) {
    838 if n == nil {
    839 return nil, errNilNode
    840 }
    841
    842 if !n.IsObject() {
    843 return nil, errNotObjectNode
    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, errNotObjectNode
    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.
    862func (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.
    874func (n *Node) AppendObject(key string, value *Node) error {
    875 if !n.IsObject() {
    876 return errInvalidAppend
    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// })
    894func (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.
    905func (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]
    929func (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.
    952func (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.
    961func (n *Node) isContainer() bool {
    962 return n.IsArray() || n.IsObject()
    963}
    964
    965// remove removes the value from the current container type node.
    966func (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.
    991func (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.
    1004func (n *Node) append(key *string, val *Node) error {
    1005 if n.isSameOrParentNode(val) {
    1006 return errInvalidAppendCycle
    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
    1034func (n *Node) isSameOrParentNode(nd *Node) bool {
    1035 return n == nd || n.isParentNode(nd)
    1036}
    1037
    1038func (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.
    1053func 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.
    1064func 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"}`))
    1077func Must(root *Node, expect error) *Node {
    1078 if expect != nil {
    1079 panic(expect)
    1080 }
    1081
    1082 return root
    1083}
    1084