Jan
Jan

Reputation: 314

Avoid/remove escape quotes in serde_json

I try to create a JSON object with serde_json::json! but the problem is that I get \" but I don't want them. How can I prevent or remove them?

fn create_cache_json(token: String, change: String, payload: Vec<Value>) -> Value {
   let json = serde_json::json!(
       {
           "token": token,  
           "change": change, 
           "data": {
               "payload": payload
           }
       });
   
   
   info!("{}", json);

   return json;
}

this code returns

{
   "change": "new",
   "data": {
       "payload":[]
   },
   "token": "2a256356"
}

EDIT: The input values are:

fn main() {
    let token = "foo".to_string();
    let change = "new".to_string();
    let payload: Vec<serde_json::Value> = Vec::new();
 
    create_cache_json(token, change, payload);
}

The input are literals that already have quotes.

The token output is: "foo" but it should be foo. Using crates like quote don't work because the values have to be strings. For this function should the payload be empty.

Upvotes: 2

Views: 3958

Answers (1)

Jan
Jan

Reputation: 314

I fixed it by changing the json! function to format! and then creating a Value from the String.

Here is the code to create a JSON object with given arguments. This should work with every datatype. If anyone else need this:

fn create_json(
     token: String, 
     change: String, 
     payload: Vec<Value>
) -> CacheEntry {

    let body: String = format!(
        "{{\"token\": {token}, \"change\": {change}, \"data\": [{:#?}] }}"
        , payload);
    let json: CacheEntry = serde_json::from_str(&body).unwrap();

    return json;
}

EDIT: As Charles Duffy said, the code above is vulnerable to injection attacks and here is a better solution:

use std::fmt;

#[derive(Debug)]
pub struct UserData {
    pub token: String,
    pub change: String,
    pub data: Payload
}

#[derive(Debug)]
pub struct Payload {
    pub payload: Vec<String>
}

impl fmt::Display for UserData {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, 
            "{{token: {:#?}, change: {:#?}, data: {:#?}}}", 
            self.token, self.change, self.data)
    }
}

fn create_cache_json(user_data: UserData) -> String {
   
    let json = user_data.to_string();
   
   println!("{}", json);

   return json;
}


fn main() {
    let p: Vec<String> = Vec::new();

    let ud = UserData {
        token: "foo".to_string(),
        change: "bar".to_string(),
        data: Payload {
            payload: p
        }
    };
    
    create_cache_json(ud);
}

Upvotes: 1

Related Questions