Search code examples
genericsrustboundsserdeserde-json

Serde_json serialize to_string with a generic


I'm trying to serialize the params paramter of the send method.

fn send<T>(method: &str, params: T) -> () {
    println!("{:?}", serde_json::to_string(&params));
    // Rest of actual code that works with 'method' and 'params'
}

fn main() {
    send::<i32>("account", 44);
    send::<&str>("name", "John");
}

But it is giving me the following error which I'm not able to solve:

the trait bound `T: primitives::_IMPL_DESERIALIZE_FOR_Address::_serde::Serialize` is not satisfied

the trait `primitives::_IMPL_DESERIALIZE_FOR_Address::_serde::Serialize` is not implemented for `T`

help: consider adding a `where T: primitives::_IMPL_DESERIALIZE_FOR_Address::_serde::Serialize` boundrustc(E0277)

I guess it is because it doesn't know the type from where it needs to serialize to although I specify it when calling send. The types passed to params could also be other structs, not only primitive types.


Solution

  • The problem is that you don't specify that everything T can be will implement the Serialize-trait. You should tell the compiler that you only intent to give it Serialize-implementors.

    A solution would be to do as the compiler says:

    help: consider adding a `where T: primitives::_IMPL_DESERIALIZE_FOR_Address::_serde::Serialize` boundrustc(E0277)
    

    So, your code should look as follows:

    fn send<T: serde::Serialize>(method: &str, params: T) -> () {
        println!("{:?}", serde_json::to_string(&params));
        // Rest of actual code that works with 'method' and 'params'
    }
    
    fn main() {
        send::<i32>("account", 44);
        send::<&str>("name", "John");
    }
    

    or using the where-keyword:

    fn send<T>(method: &str, params: T) -> () where T: serde::Serialize {
        println!("{:?}", serde_json::to_string(&params));
        // Rest of actual code that works with 'method' and 'params'
    }
    
    fn main() {
        send::<i32>("account", 44);
        send::<&str>("name", "John");
    }