diff --git a/Makefile b/Makefile index 36f5d16..1a37f86 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,8 @@ test: extism call example/tiny_countvowels.wasm count_vowels --wasi --input "this is a test" --set-config '{"thing": "1234"}' extism call example/tiny_http.wasm http_get --wasi --log-level info --allow-host "jsonplaceholder.typicode.com" extism call example/tiny_reactor.wasm read_file --input "example/reactor/test.txt" --allow-path ./example/reactor --wasi --log-level info + extism call example/tiny_countvowels.wasm count_vowels_roundtrip_json_mem --wasi extism call example/std_countvowels.wasm _start --wasi --input "this is a test" --set-config '{"thing": "1234"}' - extism call example/std_http.wasm _start --wasi --log-level info --allow-host "jsonplaceholder.typicode.com" \ No newline at end of file + extism call example/std_http.wasm _start --wasi --log-level info --allow-host "jsonplaceholder.typicode.com" + diff --git a/example/countvowels/std_main.go b/example/countvowels/std_main.go index 3f1f9f1..d41024f 100644 --- a/example/countvowels/std_main.go +++ b/example/countvowels/std_main.go @@ -17,6 +17,7 @@ func main() { countVowels() countVowelsTyped() countVowelsJSONOutput() + countVowelsJSONRoundtripMem() } // CountVowelsInput represents the JSON input provided by the host. @@ -54,6 +55,32 @@ func countVowelsJSONOutput() int32 { return 0 } +//export count_vowels_roundtrip_json_mem +func countVowelsJSONRoundtripMem() int32 { + a := CountVowelsOuptut{Count: 42, Total: 2.1e7, Vowels: "aAeEiIoOuUyY"} + mem, err := pdk.AllocateJSON(&a) + if err != nil { + pdk.SetError(err) + return -1 + } + + // find the data in mem and ensure it's the same once decoded + var b CountVowelsOuptut + err = pdk.JSONFrom(mem.Offset(), &b) + if err != nil { + pdk.SetError(err) + return -1 + } + + if a.Count != b.Count || a.Total != b.Total || a.Vowels != b.Vowels { + pdk.SetErrorString("roundtrip JSON failed") + return -1 + } + + pdk.OutputString("JSON roundtrip: a === b") + return 0 +} + func countVowels() int32 { input := pdk.Input() diff --git a/example/countvowels/tiny_main.go b/example/countvowels/tiny_main.go index e931969..6b2046f 100644 --- a/example/countvowels/tiny_main.go +++ b/example/countvowels/tiny_main.go @@ -44,6 +44,32 @@ func countVowelsJSONOutput() int32 { return 0 } +//export count_vowels_roundtrip_json_mem +func countVowelsJSONRoundtripMem() int32 { + a := CountVowelsOuptut{Count: 42, Total: 2.1e7, Vowels: "aAeEiIoOuUyY"} + mem, err := pdk.AllocateJSON(&a) + if err != nil { + pdk.SetError(err) + return -1 + } + + // find the data in mem and ensure it's the same once decoded + var b CountVowelsOuptut + err = pdk.JSONFrom(mem.Offset(), &b) + if err != nil { + pdk.SetError(err) + return -1 + } + + if a.Count != b.Count || a.Total != b.Total || a.Vowels != b.Vowels { + pdk.SetErrorString("roundtrip JSON failed") + return -1 + } + + pdk.OutputString("JSON roundtrip: a === b") + return 0 +} + //export count_vowels func countVowels() int32 { input := pdk.Input() diff --git a/extism_pdk.go b/extism_pdk.go index 2f4383a..8b4bb31 100644 --- a/extism_pdk.go +++ b/extism_pdk.go @@ -134,6 +134,16 @@ func AllocateString(data string) Memory { return AllocateBytes([]byte(data)) } +// AllocateJSON allocates and saves the type `any` into Memory on the host. +func AllocateJSON(v any) (Memory, error) { + b, err := json.Marshal(v) + if err != nil { + return Memory{}, err + } + + return AllocateBytes(b), nil +} + // InputString returns the input data from the host as a UTF-8 string. func InputString() string { return string(Input())