@@ -2,12 +2,11 @@ package stdlib
2
2
3
3
import (
4
4
"cmp"
5
- "errors"
6
5
"fmt"
7
6
"path/filepath"
8
- "reflect"
9
7
"slices"
10
8
"strings"
9
+ "time"
11
10
12
11
"github.com/expr-lang/expr"
13
12
"github.com/xhit/go-str2duration/v2"
@@ -17,12 +16,12 @@ var FilepathDir = expr.Function(
17
16
"filepath_dir" ,
18
17
func (params ... any ) (any , error ) {
19
18
if len (params ) != 1 {
20
- return nil , fmt . Errorf ("filepath_dir: accepts exactly 1 argument, %d provided" , len (params ))
19
+ return nil , NewInvalidNumberOfArgumentsError ("filepath_dir" , "" , 1 , len (params ))
21
20
}
22
21
23
22
val , ok := params [0 ].(string )
24
23
if ! ok {
25
- return nil , errors . New ( "input to filepath_dir must be of type ' string' " )
24
+ return nil , NewInvalidArgumentTypeError ( " filepath_dir" , "input must be string" )
26
25
}
27
26
28
27
return filepath .Dir (val ), nil
@@ -36,61 +35,74 @@ func UniqSlice[T cmp.Ordered](in []T) []T {
36
35
return slices .Compact (in )
37
36
}
38
37
38
+ // Uniq takes a list of strings or interface{}, sorts them
39
+ // and remove duplicated values
39
40
var Uniq = expr .Function (
40
41
"uniq" ,
41
- func (params ... any ) (any , error ) {
42
- arg := params [0 ]
43
- val := reflect .ValueOf (arg )
44
-
45
- switch val .Kind () { //nolint:exhaustive
46
- case reflect .Slice :
47
- switch val .Type ().Elem ().Kind () { //nolint:exhaustive
48
- case reflect .Interface :
49
- var x []string
50
- for _ , v := range arg .([]any ) { //nolint:forcetypeassert
51
- x = append (x , fmt .Sprintf ("%s" , v ))
52
- }
42
+ func (args ... any ) (any , error ) {
43
+ if len (args ) != 1 {
44
+ return nil , NewInvalidNumberOfArgumentsError ("uniq" , "" , 1 , len (args ))
45
+ }
53
46
54
- return UniqSlice ( x ), nil
47
+ arg := args [ 0 ]
55
48
56
- case reflect .String :
57
- return UniqSlice (arg .([]string )), nil //nolint:forcetypeassert
49
+ switch val := arg .(type ) {
50
+ case []any :
51
+ var result []string
58
52
53
+ for _ , v := range val {
54
+ result = append (result , fmt .Sprintf ("%s" , v ))
59
55
}
60
- }
61
56
62
- return nil , errors .New ("invalid type" )
57
+ return UniqSlice (result ), nil
58
+
59
+ case []string :
60
+ return UniqSlice (val ), nil
61
+
62
+ default :
63
+ return nil , NewInvalidArgumentTypeError ("uniq" , fmt .Sprintf ("invalid input, must be an array of [string] or [interface], got %T" , arg ))
64
+ }
63
65
},
66
+ new (func ([]string ) []string ),
67
+ new (func ([]any ) []string ),
64
68
)
65
69
70
+ // Override built-in duration() function to provide support for additional periods
71
+ // - 'd' (day)
72
+ // - 'w' (week)
73
+ // - 'm' (month)
66
74
var Duration = expr .Function (
67
75
"duration" ,
68
76
func (args ... any ) (any , error ) {
77
+ if len (args ) != 1 {
78
+ return nil , NewInvalidNumberOfArgumentsError ("duration" , "" , 1 , len (args ))
79
+ }
80
+
69
81
val , ok := args [0 ].(string )
70
82
if ! ok {
71
- return nil , errors . New ( "input to duration() must be of type ' string'" )
83
+ return nil , NewInvalidArgumentTypeError ( " duration" , fmt . Sprintf ( "invalid input, must be a string, got %T" , args [ 0 ]) )
72
84
}
73
85
74
86
return str2duration .ParseDuration (val )
75
87
},
76
- str2duration .ParseDuration ,
88
+ time .ParseDuration ,
77
89
)
78
90
79
91
var LimitPathDepthTo = expr .Function (
80
92
"limit_path_depth_to" ,
81
93
func (args ... any ) (any , error ) {
82
94
if len (args ) != 2 {
83
- return nil , errors . New ("limit_path_depth_to() expect exactly two arguments" )
95
+ return nil , NewInvalidNumberOfArgumentsError ("limit_path_depth_to" , "" , 2 , len ( args ) )
84
96
}
85
97
86
98
input , ok := args [0 ].(string )
87
99
if ! ok {
88
- return nil , errors . New ( "first input to limit_path_depth_to() must be of type 'string'" )
100
+ return nil , NewInvalidArgumentTypeError ( "limit_path_depth_to" , fmt . Sprintf ( "invalid input, first argument must be a 'string', got %T" , args [ 0 ]) )
89
101
}
90
102
91
103
length , ok := args [1 ].(int )
92
104
if ! ok {
93
- return nil , errors . New ( "second input to limit_path_depth_to() must be of type 'int'" )
105
+ return nil , NewInvalidArgumentTypeError ( "limit_path_depth_to" , fmt . Sprintf ( "invalid input, first argument must be an 'int', got %T" , args [ 0 ]) )
94
106
}
95
107
96
108
chunks := strings .Split (input , "/" )
@@ -100,4 +112,5 @@ var LimitPathDepthTo = expr.Function(
100
112
101
113
return strings .Join (chunks [0 :length - 1 ], "/" ), nil // nosemgrep
102
114
},
115
+ new (func (string , int ) string ),
103
116
)
0 commit comments