github.com/tomwright/dasel@v1.27.3/node_put.go (about) 1 package dasel 2 3 import ( 4 "fmt" 5 "github.com/tomwright/dasel/storage" 6 "reflect" 7 ) 8 9 // Put finds the node using the given selector and updates it's value. 10 // It then attempts to propagate the value back up the chain to the root element. 11 func (n *Node) Put(selector string, newValue interface{}) error { 12 if selector != "." { 13 n.Selector.Remaining = selector 14 } 15 16 if err := buildPutChain(n); err != nil { 17 return err 18 } 19 20 final := lastNode(n) 21 22 _, isRealValue := newValue.(storage.RealValue) 23 if isRealValue { 24 final.setRealValue(newValue) 25 } else { 26 final.setValue(newValue) 27 } 28 29 if final.Selector.Type != "ROOT" { 30 if err := propagate(final); err != nil { 31 return err 32 } 33 } 34 35 return nil 36 } 37 38 // PutMultiple all applicable nodes for the given selector and updates all of their values to the given value. 39 // It then attempts to propagate the value back up the chain to the root element. 40 func (n *Node) PutMultiple(selector string, newValue interface{}) error { 41 if selector != "." { 42 n.Selector.Remaining = selector 43 } 44 45 if err := buildPutMultipleChain(n); err != nil { 46 return err 47 } 48 49 final := lastNodes(n) 50 51 val := reflect.ValueOf(newValue) 52 _, isRealValue := newValue.(storage.RealValue) 53 54 for _, n := range final { 55 if isRealValue { 56 n.setRealReflectValue(val) 57 } else { 58 n.setReflectValue(val) 59 } 60 if err := propagate(n); err != nil { 61 return err 62 } 63 } 64 65 return nil 66 } 67 68 func buildPutChain(n *Node) error { 69 if isFinalSelector(n.Selector.Remaining) { 70 // We've reached the end 71 return nil 72 } 73 74 var err error 75 nextNode := &Node{} 76 77 // Parse the selector. 78 nextNode.Selector, err = ParseSelector(n.Selector.Remaining) 79 if err != nil { 80 return fmt.Errorf("failed to parse selector: %w", err) 81 } 82 83 // Link the nodes. 84 n.Next = nextNode 85 nextNode.Previous = n 86 87 // Populate the value for the new node. 88 nextNode.Value, err = findValue(nextNode, true) 89 if err != nil { 90 return fmt.Errorf("could not find put value: %w", err) 91 } 92 93 return buildPutChain(nextNode) 94 } 95 96 func buildPutMultipleChain(n *Node) error { 97 if isFinalSelector(n.Selector.Remaining) { 98 // We've reached the end 99 return nil 100 } 101 102 var err error 103 104 // Parse the selector. 105 nextSelector, err := ParseSelector(n.Selector.Remaining) 106 if err != nil { 107 return fmt.Errorf("failed to parse selector: %w", err) 108 } 109 110 // Populate the value for the new node. 111 n.NextMultiple, err = findNodes(nextSelector, n, true) 112 113 if err != nil { 114 return fmt.Errorf("could not find put multiple value: %w", err) 115 } 116 117 for _, next := range n.NextMultiple { 118 // Add the back reference 119 if next.Previous == nil { 120 // This can already be set in some cases - SEARCH. 121 next.Previous = n 122 } 123 124 if err := buildPutMultipleChain(next); err != nil { 125 return err 126 } 127 } 128 129 return nil 130 }