How to send json instead of String?

How to return a json instead of a string to Tauri from the users() function below?

// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
#![allow(dead_code)]
use sqlx::Row;
use std::error::Error;

fn main() {
    tauri::Builder::default()
        .invoke_handler(tauri::generate_handler![greet, foo, users])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

#[derive(Debug)]
struct User {
    pub email: String,
}

// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
#[tauri::command]
fn greet(name: &str) -> String {
    format!("Hello, {}! You've been greeted from Rust!", name)
}

#[tauri::command]
fn foo(name: &str) -> String {
    format!("Hello, {}! You've been greeted by Bob from Rust!", name)
}

#[tauri::command]
fn users() -> String {
    let users = bar();
    format!("{:?}", users.unwrap())
}

#[tokio::main]
async fn bar() -> Result<Vec<User>, Box<dyn Error>> {
    dotenv::dotenv().expect("Unable to load environment variables from .env file");
    let url = std::env::var("DATABASE_URL").expect("Unable to read DATABASE_URL env var");
    let pool = sqlx::postgres::PgPool::connect(&url).await?;
    // println!("{:?}", users);
    let q = "SELECT email FROM users";
    let query = sqlx::query(q);
    let rows = query.fetch_all(&pool).await?;
    let users = rows
        .iter()
        .map(|row| User {
            email: row.get("email"),
        })
        .collect();
    // format!("{:?}", users)
    Ok(users)
}

Maybe this is what you want?

json!(users)

That's using the json macro from serde_json.

If not, then try to be more explicit about the JSON payload that you expect.

Communication with JS is fundamentally all string-based. Rust can't make an instance of a JS Object on the Rust side, since that is a private internal representation of data in the browser engine. So any data format, like JSON, has to be sent as a string, and then parsed in JS.

You can return types from tauri::command that support serde::Serialize, which tauri will use to make a String from them automatically.

2 Likes

@kornel Thanks for you answer, I understand better.
When a string is returned with my current code, I'm getting something like:

[User { email: "me@home.com" }, User { email: "you@home.com" }]

How do I get rid of User ?

You are literally sending the Debug representation of Vec<User>. That's not JSON. Please read the documentation.

If you want to send actual JSON, you'll need to use something else. I'm sure if you had googled "Rust JSON", you would have found out about Serde and serde-json.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.