mirror of
https://github.com/TomWright/dasel.git
synced 2022-05-22 02:32:45 +03:00
Add != comparison operator support in dynamic and search selectors
This commit is contained in:
@@ -7,7 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
- Nothing
|
||||
### Added
|
||||
|
||||
- Support for `!=` comparison operator in dynamic and search selectors.
|
||||
|
||||
## [v1.16.1] - 2021-08-02
|
||||
|
||||
|
||||
@@ -12,6 +12,16 @@ type EqualCondition struct {
|
||||
Key string
|
||||
// Value is the value we are looking for.
|
||||
Value string
|
||||
// Not is true if this is a not equal check.
|
||||
Not bool
|
||||
}
|
||||
|
||||
func (c EqualCondition) check(a interface{}, b interface{}) (bool, error) {
|
||||
var res = fmt.Sprint(a) == b
|
||||
if c.Not {
|
||||
res = !res
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Check checks to see if other contains the required key value pair.
|
||||
@@ -23,7 +33,7 @@ func (c EqualCondition) Check(other reflect.Value) (bool, error) {
|
||||
value := unwrapValue(other)
|
||||
|
||||
if c.Key == "value" || c.Key == "." {
|
||||
return fmt.Sprint(value.Interface()) == c.Value, nil
|
||||
return c.check(value.Interface(), c.Value)
|
||||
}
|
||||
|
||||
switch value.Kind() {
|
||||
@@ -39,7 +49,7 @@ func (c EqualCondition) Check(other reflect.Value) (bool, error) {
|
||||
return false, fmt.Errorf("subquery failed: %w", err)
|
||||
}
|
||||
|
||||
return fmt.Sprint(foundNode.InterfaceValue()) == c.Value, nil
|
||||
return c.check(foundNode.InterfaceValue(), c.Value)
|
||||
}
|
||||
|
||||
return false, &UnhandledCheckType{Value: value.String()}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package dasel
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
@@ -8,6 +9,16 @@ import (
|
||||
type KeyEqualCondition struct {
|
||||
// Value is the value we are looking for.
|
||||
Value string
|
||||
// Not is true if this is a not equal check.
|
||||
Not bool
|
||||
}
|
||||
|
||||
func (c KeyEqualCondition) check(a interface{}, b interface{}) (bool, error) {
|
||||
var res = fmt.Sprint(a) == b
|
||||
if c.Not {
|
||||
res = !res
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Check checks to see if other contains the required key value pair.
|
||||
@@ -18,5 +29,5 @@ func (c KeyEqualCondition) Check(other reflect.Value) (bool, error) {
|
||||
|
||||
value := unwrapValue(other)
|
||||
|
||||
return c.Value == value.String(), nil
|
||||
return c.check(c.Value, value.String())
|
||||
}
|
||||
|
||||
3
go.sum
3
go.sum
@@ -34,7 +34,6 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
@@ -101,7 +100,6 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 h1:XQyxROzUlZH+WIQwySDgnISgOivlhjIEwaQaJEJrrN0=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -121,7 +119,6 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd h1:/e+gpKk9r3dJobndpTytxS2gOy6m5uvpg+ISQoEcusQ=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
|
||||
46
node_test.go
46
node_test.go
@@ -181,6 +181,19 @@ func TestParseSelector(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}))
|
||||
t.Run("SearchNotEqual", testParseSelector(".(?:name!=asd)", dasel.Selector{
|
||||
Raw: ".(?:name!=asd)",
|
||||
Current: ".(?:name!=asd)",
|
||||
Remaining: "",
|
||||
Type: "SEARCH",
|
||||
Conditions: []dasel.Condition{
|
||||
&dasel.EqualCondition{
|
||||
Key: "name",
|
||||
Value: "asd",
|
||||
Not: true,
|
||||
},
|
||||
},
|
||||
}))
|
||||
t.Run("SearchMoreThan", testParseSelector(".(?:name.[#]>3)", dasel.Selector{
|
||||
Raw: ".(?:name.[#]>3)",
|
||||
Current: ".(?:name.[#]>3)",
|
||||
@@ -244,6 +257,18 @@ func TestParseSelector(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}))
|
||||
t.Run("SearchKeyNotEqual", testParseSelector(".(?:-!=asd)", dasel.Selector{
|
||||
Raw: ".(?:-!=asd)",
|
||||
Current: ".(?:-!=asd)",
|
||||
Remaining: "",
|
||||
Type: "SEARCH",
|
||||
Conditions: []dasel.Condition{
|
||||
&dasel.KeyEqualCondition{
|
||||
Value: "asd",
|
||||
Not: true,
|
||||
},
|
||||
},
|
||||
}))
|
||||
t.Run("DynamicEqual", testParseSelector(".(name=asd)", dasel.Selector{
|
||||
Raw: ".(name=asd)",
|
||||
Current: ".(name=asd)",
|
||||
@@ -256,6 +281,19 @@ func TestParseSelector(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}))
|
||||
t.Run("DynamicNotEqual", testParseSelector(".(name!=asd)", dasel.Selector{
|
||||
Raw: ".(name!=asd)",
|
||||
Current: ".(name!=asd)",
|
||||
Remaining: "",
|
||||
Type: "DYNAMIC",
|
||||
Conditions: []dasel.Condition{
|
||||
&dasel.EqualCondition{
|
||||
Key: "name",
|
||||
Value: "asd",
|
||||
Not: true,
|
||||
},
|
||||
},
|
||||
}))
|
||||
t.Run("DynamicMoreThan", testParseSelector(".(name.[#]>3)", dasel.Selector{
|
||||
Raw: ".(name.[#]>3)",
|
||||
Current: ".(name.[#]>3)",
|
||||
@@ -383,7 +421,13 @@ func TestNode_QueryMultiple(t *testing.T) {
|
||||
t.Run("SingleResultDynamic", testNodeQueryMultipleArray(".(age=25).name", []interface{}{
|
||||
"Amelia",
|
||||
}))
|
||||
t.Run("SingleResultDynamic", testNodeQueryMultipleArray(".(age=27).name", []interface{}{
|
||||
t.Run("SingleResultDynamic", testNodeQueryMultipleArray(".(age!=27).name", []interface{}{
|
||||
"Amelia",
|
||||
}))
|
||||
t.Run("MultipleResultSearchKeyNotEqual", testNodeQueryMultipleArray(".[*].(?:-!=name)", []interface{}{
|
||||
"27", "27", "25",
|
||||
}))
|
||||
t.Run("MultipleResultDynamic", testNodeQueryMultipleArray(".(age=27).name", []interface{}{
|
||||
"Tom",
|
||||
"Jim",
|
||||
}))
|
||||
|
||||
@@ -54,15 +54,32 @@ func processParseSelectorDynamic(selector string, sel Selector) (Selector, error
|
||||
}
|
||||
|
||||
for _, g := range dynamicGroups {
|
||||
// evaluable, err := gvalInstance.NewEvaluable(g)
|
||||
// if err != nil {
|
||||
// return sel, fmt.Errorf("could not parse dynamic expression: %w", err)
|
||||
// }
|
||||
//
|
||||
// todo : how do we execute sub queries?
|
||||
// sel.Conditions = append(sel.Conditions, &GvalCondition{
|
||||
// Evaluable: evaluable,
|
||||
// })
|
||||
|
||||
m := FindDynamicSelectorParts(g)
|
||||
|
||||
var cond Condition
|
||||
|
||||
switch m.Comparison {
|
||||
case "=":
|
||||
cond = &EqualCondition{
|
||||
Key: m.Key,
|
||||
Value: m.Value,
|
||||
}
|
||||
case "!=":
|
||||
cond = &EqualCondition{
|
||||
Key: m.Key,
|
||||
Value: m.Value,
|
||||
Not: true,
|
||||
}
|
||||
case ">=":
|
||||
cond = &SortedComparisonCondition{
|
||||
Key: m.Key,
|
||||
@@ -121,6 +138,11 @@ func processParseSelectorSearch(selector string, sel Selector) (Selector, error)
|
||||
cond = &KeyEqualCondition{
|
||||
Value: m.Value,
|
||||
}
|
||||
case "!=":
|
||||
cond = &KeyEqualCondition{
|
||||
Value: m.Value,
|
||||
Not: true,
|
||||
}
|
||||
default:
|
||||
return sel, &UnknownComparisonOperatorErr{Operator: m.Comparison}
|
||||
}
|
||||
@@ -131,6 +153,12 @@ func processParseSelectorSearch(selector string, sel Selector) (Selector, error)
|
||||
Key: m.Key,
|
||||
Value: m.Value,
|
||||
}
|
||||
case "!=":
|
||||
cond = &EqualCondition{
|
||||
Key: m.Key,
|
||||
Value: m.Value,
|
||||
Not: true,
|
||||
}
|
||||
case ">=":
|
||||
cond = &SortedComparisonCondition{
|
||||
Key: m.Key,
|
||||
|
||||
Reference in New Issue
Block a user