rustserde-json

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.


Solution

  • 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);
    }