this works as long as the JSON to be decoded only contains a string, e.g. '"abc"'. However if I try to decode an object, e.g. '{"foo":123}' it throws this error as decoded.unwrap() is no longer a borrowed string:
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: Error("invalid type: map, expected a borrowed string", line: 1, column: 0)', src/lib.rs:11:33
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
fatal runtime error: failed to initiate panic, error 5
My questions at this point are: how do I define a function that can return any type (depending on the JSON content) and make the FFI call work? Should I define a union as return type? Would PHP be able to interpret the union?
For starters, use the Value enum from serde_json for decoding into an effectively dynamically-typed value.
Then, you'll have to figure out how you can convert the different variants of Value into the corresponding PHP objects (probably zval). You can get started using this tutorial.
No. Again, that's not something PHP can interpret, and it's not FFI safe (basically nothing except the most primitive types, such as ints, floats, and pointers are FFI-safe, with a few very special exceptions).
Once you have the Valueinside the function, you have to convert it to a PHP object. What precisely the signature must be and how values should be "returned" must be determined based on what the PHP_FUNCTION macro expands to. I wouldn't necessarily expect the return value of the C function to be the return value of the corresponding PHP function.
But you should probably delegate all of this highly unsafe work to an existing crate such as ext-php-rs.