-
Notifications
You must be signed in to change notification settings - Fork 63
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Type assertion fails #19
Comments
Made a few changes, see the CL above |
So I am sending data from FFI function to the runtime as an interface, this data could be any underlying type. The test scenario I worked with sends a Based on your comment in the commit above:
Consider this code: package main
import "my_ffi"
func main() {
var in = my_ffi.GetData()
// get inputs
data, ok := in.(map[string]interface{})
assert(ok)
left, _ := data["left"].(int) // <<== Type assertion error starts here
right, _ := data["right"].(int)
} How do I know what to pass into This is how I convert fn to_go_value(ctx: &FfiCtx, value: Value) -> GosValue {
match value.clone() {
....
Value::Object(m) => {
ctx.new_map(m.into_iter().map(|(k, v)|{
let _val = FfiCtx::new_interface(to_go_value(ctx, v.clone()), None); // <<== I have no idea what to use instead of `None`
(FfiCtx::new_string(&k), _val)
}).collect())
}
}
} |
I realized the previous API requires too much understanding of the inner workings, I changed it so that you need to pass the metas of the interface and the value. Which are still hard to use, will figure out some improments. For now, for your case, you can get the interface meta via PrimitiveMeta.empty_iface, and Meta::new_map() for the value. For examples, see It looks like you are trying to convert arbitrary |
I have a function that checks the internal type of the json value, fn map_go_types(v: Value) -> ValueType {
match v {
Value::Null => ValueType::Void,
Value::Bool(_) => ValueType::Bool,
Value::Number(n) => {
if n.is_f64() {
ValueType::Float64
} else if n.is_i64() {
ValueType::Int64
} else {
ValueType::Uint64
}
}
Value::String(_) => ValueType::String,
Value::Array(_) => ValueType::Array,
Value::Object(_) => ValueType::Map,
}
} For object and array, it does a recursive walk through their element values and check their types. For example, an array Value::Array(a) => {
let data = a
.iter()
.map(|d| to_go_value(ctx, d.clone())) // <<== calling to_go_value to convert element values recursively
.collect::<Vec<_>>();
ctx.new_array(data, map_go_types(value))
} This is why I rely on "interface{}" types on the Go side of things, to afford the flexibility of casting the value to the necessary type on demand. This is currently possible with the Go runtime. I am assuming for Goscript, that |
Closely watching these files, I have now created an UnsafePtr and FFI module specifically for accessing dynamic data. Looking forward to an official |
This should work in Goscript as well. |
I am excited to see Goscript fully working, it's currently an experimental embedded runtime for my project zflow. So this is how I am currently handling the data, based on your suggestion: And the goscript example looks like this: package main
import "zflow"
func main() {
// get inputs
var in = zflow.Inputs()
if !in.IsNil() {
data, ok := in.Map()
if !ok {
panic("could not read inputs")
}
left, _ := data["left"].I64()
right, _ := data["right"].I64()
// some calculation
total := left + right
packet := map[string]int64{"sum": total}
zflow.Send(packet)
}
} |
Glad to hear! Your feedback has been very helpful. |
Unwrapping
b.as_ref()
is not guaranteed, and fails sometimes when you pass an interface{} value into an ffi function.goscript/vm/src/vm.rs
Line 1843 in 04d1cb0
I wonder what the general behavior would be if you applied this as a fix
The text was updated successfully, but these errors were encountered: