Skip to content

Commit

Permalink
Add mix, max and fix IsNull issue
Browse files Browse the repository at this point in the history
  • Loading branch information
TomWright committed Oct 24, 2024
1 parent 0ffe7cc commit ba0aa78
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 2 deletions.
8 changes: 7 additions & 1 deletion cmd/dasel/main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"io"
"os"

"github.com/tomwright/dasel/v3/internal/cli"
Expand All @@ -11,5 +12,10 @@ import (
)

func main() {
cli.MustRun(os.Stdin, os.Stdout, os.Stderr)
var stdin io.Reader = os.Stdin
fi, err := os.Stdin.Stat()
if err != nil || (fi.Mode()&os.ModeNamedPipe == 0) {
stdin = nil
}
cli.MustRun(stdin, os.Stdout, os.Stderr)
}
2 changes: 2 additions & 0 deletions execution/func.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ var (
FuncMerge,
FuncReverse,
FuncTypeOf,
FuncMax,
FuncMin,
)
)

Expand Down
32 changes: 32 additions & 0 deletions execution/func_max.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package execution

import (
"github.com/tomwright/dasel/v3/model"
)

// FuncMax is a function that returns the highest number.
var FuncMax = NewFunc(
"max",
func(data *model.Value, args model.Values) (*model.Value, error) {
res := model.NewNullValue()
for _, arg := range args {
if res.IsNull() {
res = arg
continue
}
gt, err := arg.GreaterThan(res)
if err != nil {
return nil, err
}
gtBool, err := gt.BoolValue()
if err != nil {
return nil, err
}
if gtBool {
res = arg
}
}
return res, nil
},
ValidateArgsMin(1),
)
22 changes: 22 additions & 0 deletions execution/func_max_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package execution_test

import (
"testing"

"github.com/tomwright/dasel/v3/model"
)

func TestFuncMax(t *testing.T) {
t.Run("int", testCase{
s: `max(1, 2, 3)`,
out: model.NewIntValue(3),
}.run)
t.Run("float", testCase{
s: `max(1f, 2.5, 3.5)`,
out: model.NewFloatValue(3.5),
}.run)
t.Run("mixed", testCase{
s: `max(1, 2f)`,
out: model.NewFloatValue(2),
}.run)
}
32 changes: 32 additions & 0 deletions execution/func_min.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package execution

import (
"github.com/tomwright/dasel/v3/model"
)

// FuncMin is a function that returns the smalled number.
var FuncMin = NewFunc(
"min",
func(data *model.Value, args model.Values) (*model.Value, error) {
res := model.NewNullValue()
for _, arg := range args {
if res.IsNull() {
res = arg
continue
}
lt, err := arg.LessThan(res)
if err != nil {
return nil, err
}
ltBool, err := lt.BoolValue()
if err != nil {
return nil, err
}
if ltBool {
res = arg
}
}
return res, nil
},
ValidateArgsMin(1),
)
22 changes: 22 additions & 0 deletions execution/func_min_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package execution_test

import (
"testing"

"github.com/tomwright/dasel/v3/model"
)

func TestFuncMin(t *testing.T) {
t.Run("int", testCase{
s: `min(1, 2, 3)`,
out: model.NewIntValue(1),
}.run)
t.Run("float", testCase{
s: `min(1f, 2.5, 3.5)`,
out: model.NewFloatValue(1),
}.run)
t.Run("mixed", testCase{
s: `min(1, 2f)`,
out: model.NewIntValue(1),
}.run)
}
15 changes: 15 additions & 0 deletions model/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,21 @@ func (v *Value) UnpackUntilKind(k reflect.Kind) (*Value, error) {
}
}

// UnpackUntilKinds unpacks the reflect value until it matches the given kind.
func (v *Value) UnpackUntilKinds(kinds ...reflect.Kind) (*Value, error) {
res := v.Value
for {
if slices.Contains(kinds, res.Kind()) {
return NewValue(res), nil
}
if res.Kind() == reflect.Interface || res.Kind() == reflect.Ptr && !res.IsNil() {
res = res.Elem()
continue
}
return nil, fmt.Errorf("could not unpack to kinds: %v", kinds)
}
}

// Type returns the type of the value.
func (v *Value) Type() Type {
switch {
Expand Down
7 changes: 6 additions & 1 deletion model/value_literal.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@ func (v *Value) IsNull() bool {
}

func (v *Value) isNull() bool {
return v.Value.IsNil()
// This logic can be cleaned up.
unpacked, err := v.UnpackUntilKinds(reflect.Chan, reflect.Func, reflect.Map, reflect.Pointer, reflect.UnsafePointer, reflect.Interface, reflect.Slice)
if err != nil {
return false
}
return unpacked.Value.IsNil()
}

// NewStringValue creates a new Value with a string value.
Expand Down

0 comments on commit ba0aa78

Please sign in to comment.