Avoid the use of `serde_json::Value` in `DeserializeFlat`
- Dominant language
- TypeScript
- Stars
- 53
- Forks
- 15
- PR merge metrics
- No merged PRs in 30d
Description
The purpose of the [DeserializeFlat](https://github.com/hackbg/fadroma/blob/21.09/lib/derive-contract/src/deserialize_flat.rs) derive macro is to avoid the nested JSON representation of enum tuple variants. This is really important when we want integrate with external services/apps like the [Keplr](https://www.keplr.app/) wallet that expect an exact message format. We can't simply not utilize tuple variants as this is how reusable contract components are implemented in the `derive-contract` macro.
A practical example is trying to create a SecretNetwork viewing key via Keplr. Keplr expects the contract to accept the following message: `{ set_viewing_key: { key: "my_key", padding: null } }`, which would require the handle message enum in our contract to have a variant that looks like this:
```rust
#[derive(Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum HandleMsg {
SetViewingKey {
key: String,
padding: Option,
}
}
```
We can avoid implementing this logic in our contract by using Fadroma's auth module and including it in the contract definition. However, the resulting message generated by the `derive-contract` macro will look something like this:
```rust
#[derive(Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum HandleMsg {
Auth(AuthHandleMsg)
}
```
making the JSON that the contract actually accepts to be this: `{ auth: { set_viewing_key: { key: "my_key", padding: null } } }`.
`DeserializeFlat` provides a custom implementation of the `serde::de::Deserialize` trait that tries to deserialize the incoming JSON as the standard `derive(Deserialize)` would first and if that fails, it tries to deserialize each of the tuple enum variants directly (in the above example that would the `AuthHandleMsg` type).
The current implementation of this macro makes use of `serde_json`'s [Value](https://docs.serde.rs/serde_json/enum.Value.html) type which defeats the entire purpose of the `serde_json_wasm` crate to not use dynamic memory allocation so this is not really usable in its current state. It also doesn't actually work, since calls to `deserialize_any` are forbidden in `serde_json_wasm` and this method is called by the `serde_json::Value` type.
How can the current logic be implemented without using `serde_json` or ideally, not having knowledge of what `Deserializer` implementation is actually being used. Alternative ideas are very welcome as well!
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.