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

Make our Uint types homogenous and create a macro for them (keep it DRY!) #1114

Closed
uint opened this issue Sep 28, 2021 · 7 comments
Closed

Comments

@uint
Copy link
Contributor

uint commented Sep 28, 2021

Homogenous meaning it'd be cool if they all used the same thing internally (e.g. Parity's uint types).

A macro (or maybe some sort of generic implementation using const generics?) would help us write all the methods, operator implementations, etc. once only rather than copy-pasting code.

@webmaster128
Copy link
Member

Note: the macro is only for code generation inside of cosmwasm_std. The usage of the types should not need to use a macro.

@webmaster128
Copy link
Member

I was wondering if we should have two macros:

  1. One based on primitives u64 and u128
  2. One based on parity U***

This has two advantages

  • no need for the overhead of U*** in case a primitive exists
  • we can utilize all standard library funtions of the primitives
  • (less change from the status quo)

@uint
Copy link
Contributor Author

uint commented Oct 4, 2021

I was wondering if we should have two macros:
...

We could try doing something like that and seeing how well it works, sure.

@uint uint self-assigned this Oct 12, 2021
@archseer
Copy link

archseer commented Nov 6, 2021

For primitives you could simply provide serializers and have users use them in their schemas, that's how we've dealt with i128:

pub mod int128 {
    use serde::{self, Deserialize, Deserializer, Serializer};

    pub fn serialize<S>(bigint: &i128, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_str(&bigint.to_string())
    }

    pub fn deserialize<'de, D>(deserializer: D) -> Result<i128, D::Error>
    where
        D: Deserializer<'de>,
    {
        let str = String::deserialize(deserializer)?;
        str::parse::<i128>(&str).map_err(serde::de::Error::custom)
    }
}

It becomes slightly more code in serializable structs:

    #[serde(with = "int128")]
    #[schemars(with = "i128")]
    pub value: i128,

but we get to use the native types without wrapper methods.

@webmaster128
Copy link
Member

webmaster128 commented Nov 6, 2021

Nice trick, @archseer. I wasn't aware it's that easy to build custom serializers. We'll still keep our types, but good to know.

@uint uint removed their assignment Oct 12, 2022
@ethanfrey
Copy link
Member

We added u128 and i128 support to serde-json-wasm: CosmWasm/serde-json-wasm#32

Can we consider this closed now?

@webmaster128
Copy link
Member

I'm not convinced that we need macros to avoid the duplication. Especially since Uint{64,128} and Uint{256,512} are implemented differently. It would help against forgetting APIs at the cost of indirection and harder code. I'm not against it but certainly not a priority. If this gets useful later, let's discuss more specific what exactly should be DRYed and how.

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

4 participants