github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/builtins/core/datatools/alter.go (about)

     1  package datatools
     2  
     3  import (
     4  	"github.com/lmorg/murex/config/defaults"
     5  	"github.com/lmorg/murex/lang"
     6  	"github.com/lmorg/murex/lang/types"
     7  	"github.com/lmorg/murex/utils/alter"
     8  )
     9  
    10  func init() {
    11  	lang.DefineMethod("alter", cmdAlter, types.Unmarshal, types.Marshal)
    12  
    13  	defaults.AppendProfile(`
    14  		autocomplete: set alter { [{
    15  			"AnyValue": true,
    16  			"ExecCmdline": true,
    17  			"AutoBranch": true,
    18  			"Dynamic": ({ -> struct-keys }),
    19  			"FlagsDesc": {
    20  				"--merge": "Merge data structures rather than overwrite",
    21  				"--sum": "Sum values in a map, merge items in an array"
    22  			},
    23  			"FlagValues": {
    24  				"-m": [{
    25  					"AnyValue": true,
    26  					"ExecCmdline": true,
    27  					"AutoBranch": true,
    28  					"Dynamic": ({ -> struct-keys })
    29  				}],
    30  				"--merge": [{
    31  					"AnyValue": true,
    32  					"ExecCmdline": true,
    33  					"AutoBranch": true,
    34  					"Dynamic": ({ -> struct-keys })
    35  				}],
    36  
    37  				"-s": [{
    38  					"AnyValue": true,
    39  					"ExecCmdline": true,
    40  					"AutoBranch": true,
    41  					"Dynamic": ({ -> struct-keys })
    42  				}],
    43  				"--sum": [{
    44  					"AnyValue": true,
    45  					"ExecCmdline": true,
    46  					"AutoBranch": true,
    47  					"Dynamic": ({ -> struct-keys })
    48  				}]
    49  			}
    50  		} ]}
    51  	`)
    52  }
    53  
    54  func cmdAlter(p *lang.Process) error {
    55  	dt := p.Stdin.GetDataType()
    56  	p.Stdout.SetDataType(dt)
    57  
    58  	const (
    59  		alterAlter int = 0
    60  		alterMerge int = iota + 1
    61  		alterSum
    62  	)
    63  
    64  	var (
    65  		action int
    66  		offset int
    67  	)
    68  
    69  	if err := p.ErrIfNotAMethod(); err != nil {
    70  		return err
    71  	}
    72  
    73  	v, err := lang.UnmarshalData(p, dt)
    74  	if err != nil {
    75  		return err
    76  	}
    77  
    78  	s, err := p.Parameters.String(0)
    79  	if err != nil {
    80  		return err
    81  	}
    82  
    83  	if s == "-m" || s == "--merge" {
    84  		action = alterMerge
    85  		offset++
    86  
    87  		s, err = p.Parameters.String(1)
    88  		if err != nil {
    89  			return err
    90  		}
    91  	}
    92  
    93  	if s == "-s" || s == "--sum" {
    94  		action = alterSum
    95  		offset++
    96  
    97  		s, err = p.Parameters.String(1)
    98  		if err != nil {
    99  			return err
   100  		}
   101  	}
   102  
   103  	newS, err := p.Parameters.String(1 + offset)
   104  	if err != nil {
   105  		return err
   106  	}
   107  	new := alter.StrToInterface(newS)
   108  
   109  	path, err := alter.SplitPath(s)
   110  	if err != nil {
   111  		return err
   112  	}
   113  
   114  	switch action {
   115  	default:
   116  		v, err = alter.Alter(p.Context, v, path, new)
   117  		if err != nil {
   118  			return err
   119  		}
   120  
   121  	case alterMerge:
   122  		v, err = alter.Merge(p.Context, v, path, new)
   123  		if err != nil {
   124  			return err
   125  		}
   126  
   127  	case alterSum:
   128  		v, err = alter.Sum(p.Context, v, path, new)
   129  		if err != nil {
   130  			return err
   131  		}
   132  	}
   133  
   134  	b, err := lang.MarshalData(p, dt, v)
   135  	if err != nil {
   136  		return err
   137  	}
   138  
   139  	_, err = p.Stdout.Write(b)
   140  	return err
   141  }