Skip to content
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

Look at serde(flatten) to simplify return value composition #57

Closed
4 tasks
ethanfrey opened this issue Aug 26, 2020 · 2 comments
Closed
4 tasks

Look at serde(flatten) to simplify return value composition #57

ethanfrey opened this issue Aug 26, 2020 · 2 comments

Comments

@ethanfrey
Copy link
Member

ethanfrey commented Aug 26, 2020

https://serde.rs/attr-flatten.html

When we try to "extend" structs, especially those we serialize but don't deserialize (query responses), rather than copy the definition and add more fields, we could embed it.

Here is an example to explain what I mean. AllowanceResponse is extended to AllowanceInfo. Currently that looks like:

#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug, Default)]
pub struct AllowanceResponse {
    pub allowance: Uint128,
    pub expires: Expiration,
}

#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug, Default)]
pub struct AllowanceInfo {
    pub spender: HumanAddr,
    pub allowance: Uint128,
    pub expires: Expiration,
}

Maybe it would be possible to do:

#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug, Default)]
pub struct AllowanceInfo {
    #[serde(flatten)]
    pub base: AllowanceResponse,
    pub expires: Expiration,
}

This PR should not only worry about the code compiling and working in Rust, but also check the JSON schema we expose externally. This can be demo-ed on a few values like above and then we can see if this works at all, and if it works, if it simplifies or complicates things.

Note: This may not work with the custom serde-json-wasm library we use. If flatten is not supported, or raises errors, then please raise an issue on that repo (our custom json lib) and close this issue. (We are unlikely to implement it)

Deliverables:

  • Update AllowanceInfo as defined
  • Update all contracts to use it properly
  • Check generated json schema (should be the same) and manually print out an example of serializing it
  • Test serializing/deserializing with this struct

In addition, please provide a short response if this seems to make the coding simpler (extending single query to enumerable) and if you feel it improves code quality, a list of other structs to consider in future issues. (This may just add confusion, and we may not make this change, but I wanted to try it out before building too many List queries)

@whalelephant
Copy link
Contributor

Please see CosmWasm/serde-json-wasm#20

for future reference: the schema produced for both flattened and unflattened struct are equal.

fn flattened_struct_should_make_correct_schema() {
        #[derive(Serialize, PartialEq, JsonSchema)]
        struct UnflatternedAllowanceInfo {
            pub allowance: Uint128,
            pub expires: Expiration,
            pub spender: HumanAddr,
        }

        let mut unflat_schema = schema_for!(UnflatternedAllowanceInfo);

        //flattened struct
        let flat_schema = schema_for!(AllowanceInfo);

        // manually renaming unflattened struct for comparison
        if let Some(m) = unflat_schema.schema.metadata.as_deref_mut() {
            m.title = Some(String::from("AllowanceInfo"));
        }

        assert_eq!(unflat_schema, flat_schema); // equal
}

@ethanfrey
Copy link
Member Author

This was shown not to work with serde-json-wasm, although it would make code cleaner if we used serde-json.

Closing this. Maybe we can revisit this when we revisit the serialization library (again)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants