neon-bindings / neon

Rust bindings for writing safe and fast native Node.js modules.
https://www.neon-bindings.com/
Apache License 2.0
7.98k stars 282 forks source link

improve(neon): Use autoref specialization for JSON wrapping return values in exported functions #1057

Closed kjvalencik closed 1 month ago

kjvalencik commented 1 month ago

Currently, the #[neon::export] macro attempts to determine if the return value is a Result by parsing the signature and reading the name. This is only used in combination with the json attribute to determine how to properly wrap with the Json extract helper.

However, we can leverage autoref specialization for much more reliable handling. This is very important for supporting async functions because we can not easily see the output type in the signature.

This PR introduces new macro hidden trait types that can be used to extract the Rust value into a JS value. The Json variant is specialized for Result<T, E> while having a blanket implementation for &T. Since we have an owned self, autoref specialization will prefer our specialized type and fallback to the blanket impl.

This works because the Serialize trait only needs to borrow the data. However, if owned data is needed, it's possible to extend this pattern with the technique anyhow uses--the specialized trait takes a reference and returns a sigil that then in turn takes the owned value.