diff --git a/README.md b/README.md index fa03f8e..b8ac899 100644 --- a/README.md +++ b/README.md @@ -116,18 +116,19 @@ type Sum struct { //export add func add() int32 { params := Add{} - err := json.Unmarshal(pdk.Input(), ¶ms) + // use json input helper, which automatically unmarshals the plugin input into your struct + err := pdk.InputJSON(¶ms) if err != nil { pdk.SetError(err) return 1 } sum := Sum{Sum: params.A + params.B} - output, err := json.Marshal(sum) + // use json output helper, which automatically marshals your struct to the plugin output + output, err := pdk.OutputJSON(sum) if err != nil { pdk.SetError(err) return 1 } - pdk.Output(output) return 0 } ``` diff --git a/example/countvowels/std_main.go b/example/countvowels/std_main.go index f371206..24c37c2 100644 --- a/example/countvowels/std_main.go +++ b/example/countvowels/std_main.go @@ -4,6 +4,7 @@ package main import ( + // "fmt" "strconv" "github.com/extism/go-pdk" @@ -13,10 +14,45 @@ import ( // `_start` via WASI. So, `main` functions should contain the plugin behavior, that the host will // invoke by explicitly calling `_start`. func main() { - countVowels() + count_vowels() + count_vowels_typed() + count_vowels_json_output() } -func countVowels() int32 { +type CountVowelsInput struct { + Input string `json:"input"` +} + +type CountVowelsOuptut struct { + Count int `json:"count"` + Total int `json:"total"` + Vowels string `json:"vowels"` +} + +//export count_vowels_typed +func count_vowels_typed() int32 { + var input CountVowelsInput + if err := pdk.InputJSON(&input); err != nil { + pdk.SetError(err) + return -1 + } + + pdk.OutputString(input.Input) + return 0 +} + +//export count_vowels_json_output +func count_vowels_json_output() int32 { + output := CountVowelsOuptut{Count: 42, Total: 2.1e7, Vowels: "aAeEiIoOuUyY"} + err := pdk.OutputJSON(output) + if err != nil { + pdk.SetError(err) + return -1 + } + return 0 +} + +func count_vowels() int32 { input := pdk.Input() count := 0 diff --git a/example/countvowels/tiny_main.go b/example/countvowels/tiny_main.go index 7b7f9e0..fd45ba6 100644 --- a/example/countvowels/tiny_main.go +++ b/example/countvowels/tiny_main.go @@ -9,6 +9,39 @@ import ( "github.com/extism/go-pdk" ) +type CountVowelsInput struct { + Input string `json:"input"` +} + +type CountVowelsOuptut struct { + Count int `json:"count"` + Total int `json:"total"` + Vowels string `json:"vowels"` +} + +//export count_vowels_typed +func count_vowels_typed() int32 { + var input CountVowelsInput + if err := pdk.InputJSON(&input); err != nil { + pdk.SetError(err) + return -1 + } + + pdk.OutputString(input.Input) + return 0 +} + +//export count_vowels_json_output +func count_vowels_json_output() int32 { + output := CountVowelsOuptut{Count: 42, Total: 2.1e7, Vowels: "aAeEiIoOuUyY"} + err := pdk.OutputJSON(output) + if err != nil { + pdk.SetError(err) + return -1 + } + return 0 +} + //export count_vowels func count_vowels() int32 { input := pdk.Input() diff --git a/extism_pdk.go b/extism_pdk.go index 291acfb..7ff8794 100644 --- a/extism_pdk.go +++ b/extism_pdk.go @@ -77,6 +77,25 @@ func Input() []byte { return loadInput() } +func JSONFrom(offset uint64, v any) error { + mem := FindMemory(offset) + return json.Unmarshal(mem.ReadBytes(), v) +} + +func InputJSON(v any) error { + return json.Unmarshal(Input(), v) +} + +func OutputJSON(v any) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + OutputMemory(AllocateBytes(b)) + return nil +} + func Allocate(length int) Memory { clength := uint64(length) offset := extism_alloc(clength)