Skip to content

Commit

Permalink
Add pipeline functions (#121)
Browse files Browse the repository at this point in the history
* Add pipeline functions

* Add pipeline functions
  • Loading branch information
tanyanliang110 authored Nov 13, 2024
1 parent 822ded9 commit 6084c1a
Show file tree
Hide file tree
Showing 6 changed files with 285 additions and 5 deletions.
12 changes: 7 additions & 5 deletions pipeline/ptinput/funcs/all.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ var FuncsMap = map[string]runtime.FuncCall{
"pt_kvs_del": FnPtKvsDel.Call,
"pt_kvs_keys": FnPtKvsKeys.Call,
"hash": FnHash.Call,
"slice_string": FnSliceString.Call,

// disable
"json_all": JSONAll,
Expand Down Expand Up @@ -187,11 +188,12 @@ var FuncsCheckMap = map[string]runtime.FuncCheck{
"point_window": PtWindowChecking,
"window_hit": PtWindowHitChecking,

"pt_kvs_set": FnPtKvsSet.Check,
"pt_kvs_get": FnPtKvsGet.Check,
"pt_kvs_del": FnPtKvsDel.Check,
"pt_kvs_keys": FnPtKvsKeys.Check,
"hash": FnHash.Check,
"pt_kvs_set": FnPtKvsSet.Check,
"pt_kvs_get": FnPtKvsGet.Check,
"pt_kvs_del": FnPtKvsDel.Check,
"pt_kvs_keys": FnPtKvsKeys.Check,
"hash": FnHash.Check,
"slice_string": FnSliceString.Check,

// disable
"json_all": JSONAllChecking,
Expand Down
2 changes: 2 additions & 0 deletions pipeline/ptinput/funcs/all_doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ var PipelineFunctionDocs = map[string]*PLDoc{
"pt_kvs_del()": FnPtKvsDel.Doc[0],
"pt_kvs_keys()": FnPtKvsKeys.Doc[0],
"hash()": FnHash.Doc[0],
"slice_string()": FnSliceString.Doc[0],
}

var PipelineFunctionDocsEN = map[string]*PLDoc{
Expand Down Expand Up @@ -161,6 +162,7 @@ var PipelineFunctionDocsEN = map[string]*PLDoc{
"pt_kvs_del()": FnPtKvsDel.Doc[1],
"pt_kvs_keys()": FnPtKvsKeys.Doc[1],
"hash()": FnHash.Doc[1],
"slice_string()": FnSliceString.Doc[1],
}

// embed docs.
Expand Down
81 changes: 81 additions & 0 deletions pipeline/ptinput/funcs/fn_slice_string.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package funcs

import (
_ "embed"

"github.com/GuanceCloud/platypus/pkg/ast"
"github.com/GuanceCloud/platypus/pkg/engine/runtime"
"github.com/GuanceCloud/platypus/pkg/errchain"
)

// embed docs.
var (
//go:embed md/slice_string.md
docSliceString string

//go:embed md/slice_string.en.md
docSliceStringEN string

// todo: parse function definition
_ = "fn slice_string(name: str, start: int, end: int) -> str"

FnSliceString = NewFunc(
"slice_string",
[]*Param{
{
Name: "name",
Type: []ast.DType{ast.String},
},
{
Name: "start",
Type: []ast.DType{ast.Int},
},
{
Name: "end",
Type: []ast.DType{ast.Int},
},
},
[]ast.DType{ast.String},
[2]*PLDoc{
{
Language: langTagZhCN, Doc: docSliceString,
FnCategory: map[string][]string{
langTagZhCN: {cStringOp}},
},
{
Language: langTagEnUS, Doc: docSliceStringEN,
FnCategory: map[string][]string{
langTagEnUS: {eStringOp}},
},
},
sliceString,
)
)

func sliceString(ctx *runtime.Task, funcExpr *ast.CallExpr, vals ...any) *errchain.PlError {
errstring := ""
if len(vals) != 3 {
ctx.Regs.ReturnAppend(errstring, ast.String)
return nil
}
name := vals[0].(string)
start, ok := vals[1].(int64)
if !ok {
ctx.Regs.ReturnAppend(errstring, ast.String)
return nil
}
end, ok := vals[2].(int64)
if !ok {
ctx.Regs.ReturnAppend(errstring, ast.String)
return nil
}
if start < 0 || end > int64(len(name)) || start > end {
ctx.Regs.ReturnAppend(errstring, ast.String)
return nil
}

substring := name[start:end]

ctx.Regs.ReturnAppend(substring, ast.String)
return nil
}
159 changes: 159 additions & 0 deletions pipeline/ptinput/funcs/fn_slice_string_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
// Unless explicitly stated otherwise all files in this repository are licensed
// under the MIT License.
// This product includes software developed at Guance Cloud (https://www.guance.com/).
// Copyright 2021-present Guance, Inc.

package funcs

import (
"testing"
"time"

"github.com/GuanceCloud/cliutils/pipeline/ptinput"
"github.com/GuanceCloud/cliutils/point"
"github.com/stretchr/testify/assert"
)

func TestSliceString(t *testing.T) {
funcs := []*Function{
FnPtKvsGet,
FnPtKvsDel,
FnPtKvsSet,
FnPtKvsKeys,
FnSliceString,
}

cases := []struct {
name, pl, in string
keyName string
expect interface{}
fail bool
}{
{
name: "normal1",
pl: `
substring = slice_string("15384073392",0,3)
pt_kvs_set("result", substring)
`,
keyName: "result",
expect: "153",
fail: false,
},
{
name: "normal2",
pl: `
substring = slice_string("15384073392",5,10)
pt_kvs_set("result", substring)
`,
keyName: "result",
expect: "07339",
fail: false,
},
{
name: "normal3",
pl: `
substring = slice_string("abcdefghijklmnop",0,10)
pt_kvs_set("result", substring)
`,
keyName: "result",
expect: "abcdefghij",
fail: false,
},
{
name: "out of range1",
pl: `
substring = slice_string("abcdefghijklmnop",-1,10)
pt_kvs_set("result", substring)
`,
keyName: "result",
expect: "",
fail: false,
},
{
name: "out of range2",
pl: `
substring = slice_string("abcdefghijklmnop",0,100)
pt_kvs_set("result", substring)
`,
keyName: "result",
expect: "",
fail: false,
},
{
name: "not integer1",
pl: `
substring = slice_string("abcdefghijklmnop","a","b")
pt_kvs_set("result", substring)
`,
keyName: "result",
expect: "",
fail: true,
},
{
name: "not integer2",
pl: `
substring = slice_string("abcdefghijklmnop","abc","def")
pt_kvs_set("result", substring)
`,
keyName: "result",
expect: "",
fail: true,
},
{
name: "not string",
pl: `
substring = slice_string(12345,0,3)
pt_kvs_set("result", substring)
`,
keyName: "result",
expect: "",
fail: true,
},
{
name: "not correct args",
pl: `
substring = slice_string("abcdefghijklmnop",0)
pt_kvs_set("result", substring)
`,
keyName: "result",
expect: "",
fail: true,
},
{
name: "not correct args",
pl: `
substring = slice_string("abcdefghijklmnop",0,1,2)
pt_kvs_set("result", substring)
`,
keyName: "result",
expect: "",
fail: true,
},
}

for idx, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
script, err := parseScipt(tc.pl, funcs)
if err != nil {
if tc.fail {
t.Logf("[%d]expect error: %s", idx, err)
} else {
t.Errorf("[%d] failed: %s", idx, err)
}
return
}

pt := ptinput.NewPlPoint(
point.Logging, "test", nil, map[string]any{"message": tc.in}, time.Now())
errR := script.Run(pt, nil)
if errR != nil {
t.Fatal(errR.Error())
}

v, _, _ := pt.Get(tc.keyName)
assert.Equal(t, tc.expect, v)
t.Logf("[%d] PASS", idx)

})
}
}
18 changes: 18 additions & 0 deletions pipeline/ptinput/funcs/md/slice_string.en.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
### `slice_string()` {#fn_slice_string}

Function prototype: `fn slice_string(name: str, start: int, end: int) -> str`

Function description: Returns the substring of the string from index start to end.

Function Parameters:

- `name`: The string to be sliced
- `start`: The starting index of the substring (inclusive)
- `end`: The ending index of the substring (exclusive)

Example:

```python
substring = slice_string("15384073392", 0, 3)
# substring will be "153"
```
18 changes: 18 additions & 0 deletions pipeline/ptinput/funcs/md/slice_string.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
### `slice_string()` {#fn_slice_string}

函数原型:`fn slice_string(name: str, start: int, end: int) -> str`

函数说明:返回字符串从索引 start 到 end 的子字符串。

函数参数:

- `name`: 要截取的字符串
- `start`: 子字符串的起始索引(包含)
- `end`: 子字符串的结束索引(不包含)

示例:

```python
substring = slice_string("15384073392", 0, 3)
# substring 的值为 "153"
```

0 comments on commit 6084c1a

Please sign in to comment.