Search code examples
rustclone

How to avoid clones when using postgres_types::Json?


I'm currently doing a rust app which uses tokio postgres and i need to make a sql request to fetch some data based on a jsonb row. The problem is that tokio postgres use a particular type (postgres_types::Json) which can be used like this : &Json::<Struct>(struct_var). The struct var can't be a reference so the Json takes ownership which raises a problem as i need to use one of the struct's field after. I could solve the problem using clone but i wanted to know before if there was an other solution which would not lower the performances. Here is the function :

pub async fn user_exists_ipv4(
    pool: &Pool,
    ip: IpAddr,
    device: &Device,
) -> Result<Option<Uuid>, String> {
    // Get a connection from the pool
    let conn = get_connection(pool).await?;
    let country = &device.country[..];
    // Get the user id from the database
    let result = conn
        .query(
            FETCH_USER_QUERY_FOR_V4,
            &[
                &ip.to_string(),
                &Json::<Device>(device.clone()),
                &country.to_string(),
            ],
        )
        .await?
    ...

Solution

  • You can use references with Json, it is simply a wrapper that implements ToSql for types that are Serialize-able. That will include &T where T: Serialize. So you can use it with device directly as it is:

    &Json::<&Device>(device)
    

    You also don't need to annotate the type of Json explicitly since it can be inferred directly from what you pass to it. The code above could be more succinctly written as:

    &Json(device)