github.com/tomwright/dasel@v1.27.3/node_delete.go (about)

     1  package dasel
     2  
     3  import "reflect"
     4  
     5  // Delete uses the given selector to find and delete the final node from the current node.
     6  func (n *Node) Delete(selector string) error {
     7  	if isFinalSelector(selector) {
     8  		n.setReflectValue(initialiseEmptyOfType(n.Value))
     9  		return nil
    10  	}
    11  
    12  	n.Selector.Remaining = selector
    13  	rootNode := n
    14  
    15  	if err := buildFindChain(rootNode); err != nil {
    16  		return err
    17  	}
    18  
    19  	finalNode := lastNode(rootNode)
    20  
    21  	if err := deleteFromParent(finalNode); err != nil {
    22  		return err
    23  	}
    24  	if finalNode.Previous != nil {
    25  		if newSlice, changed := cleanupSliceDeletions(finalNode.Previous.Value); changed {
    26  			finalNode.Previous.setReflectValue(newSlice)
    27  		}
    28  
    29  		if finalNode.Previous.Selector.Type != "ROOT" {
    30  			if err := propagate(finalNode.Previous); err != nil {
    31  				return err
    32  			}
    33  		}
    34  	}
    35  
    36  	return nil
    37  }
    38  
    39  // DeleteMultiple uses the given selector to query the current node for every match
    40  // possible and deletes them from the current node.
    41  func (n *Node) DeleteMultiple(selector string) error {
    42  	if selector == "." {
    43  		n.setReflectValue(initialiseEmptyOfType(n.Value))
    44  		return nil
    45  	}
    46  
    47  	n.Selector.Remaining = selector
    48  
    49  	if err := buildFindMultipleChain(n); err != nil {
    50  		return err
    51  	}
    52  
    53  	lastNodes := lastNodes(n)
    54  	for _, lastNode := range lastNodes {
    55  		// delete properties and mark indexes for deletion
    56  		if err := deleteFromParent(lastNode); err != nil {
    57  			return err
    58  		}
    59  	}
    60  
    61  	for _, lastNode := range lastNodes {
    62  		// Cleanup indexes marked for deletion
    63  		if lastNode.Previous != nil {
    64  			if newSlice, changed := cleanupSliceDeletions(lastNode.Previous.Value); changed {
    65  				lastNode.Previous.setReflectValue(newSlice)
    66  			}
    67  		}
    68  	}
    69  	for _, lastNode := range lastNodes {
    70  		// Propagate values
    71  		if lastNode.Previous != nil {
    72  			if lastNode.Previous.Selector.Type != "ROOT" {
    73  				if err := propagate(lastNode.Previous); err != nil {
    74  					return err
    75  				}
    76  			}
    77  		}
    78  	}
    79  
    80  	return nil
    81  }
    82  
    83  func initialiseEmptyOfType(value reflect.Value) reflect.Value {
    84  	value = unwrapValue(value)
    85  	switch value.Kind() {
    86  	case reflect.Slice:
    87  		return reflect.MakeSlice(value.Type(), 0, 0)
    88  	case reflect.Map:
    89  		return reflect.MakeMap(value.Type())
    90  	default:
    91  		return reflect.ValueOf(map[string]interface{}{})
    92  	}
    93  }