@@ -119,14 +119,59 @@ func binaryOp(op jsonpath.OperationType, left jsonpath.Path, right jsonpath.Path
119119 }
120120}
121121
122- func unaryOp (op jsonpath.OperationType, left jsonpath.Path) jsonpath.Operation {
122+ func unaryOp (op jsonpath.OperationType, left jsonpath.Path) jsonpath.Path {
123+ if scalar, ok := maybeNormalizeUnaryOp (op, left); ok {
124+ return scalar
125+ }
123126 return jsonpath.Operation {
124127 Type: op,
125128 Left: left,
126129 Right: nil,
127130 }
128131}
129132
133+ func maybeNormalizeUnaryOp (op jsonpath.OperationType, expr jsonpath.Path) (jsonpath.Scalar, bool ) {
134+ // Return if not unary plus or unary minus.
135+ if op != jsonpath.OpPlus && op != jsonpath.OpMinus {
136+ return jsonpath.Scalar {}, false
137+ }
138+
139+ scalar, ok := extractNumericScalar (expr)
140+ if !ok {
141+ return jsonpath.Scalar {}, false
142+ }
143+ if op == jsonpath.OpMinus {
144+ dec, _ := scalar.Value .AsDecimal ()
145+ dec.Neg (dec)
146+ scalar.Value = json.FromDecimal (*dec)
147+ }
148+ return scalar, true
149+ }
150+
151+ // extractNumericScalar attempts to extract a numeric scalar value from a
152+ // jsonpath.Path. It handles two cases:
153+ // - Direct scalar values.
154+ // - Scalar values wrapped in a jsonpath.Paths object of length 1.
155+ // The function returns the scalar and true if the path contains a valid numeric
156+ // value (integer or float), otherwise returns an empty scalar and false.
157+ func extractNumericScalar (expr jsonpath.Path) (jsonpath.Scalar, bool ) {
158+ potentialScalar := expr
159+ if paths, ok := expr.(jsonpath.Paths ); ok {
160+ if len (paths) != 1 {
161+ return jsonpath.Scalar {}, false
162+ }
163+ potentialScalar = paths[0 ]
164+ }
165+ scalar, ok := potentialScalar.(jsonpath.Scalar )
166+ if !ok {
167+ return jsonpath.Scalar {}, false
168+ }
169+ if scalar.Type != jsonpath.ScalarFloat && scalar.Type != jsonpath.ScalarInt {
170+ return jsonpath.Scalar {}, false
171+ }
172+ return scalar, true
173+ }
174+
130175func regexBinaryOp (left jsonpath.Path, regex string) (jsonpath.Operation, error) {
131176 r := jsonpath.Regex {Regex: regex}
132177 _, err := ReCache.GetRegexp (r)
0 commit comments