skip to Main Content

I want to extract some information about my json string but I have some issue when I try to do it.

This is the style of my string in json format:

{
    "id": "my_id",
    "field1": {
        "value": true,
        "test": true
    },
    "target": {
        "value1": "value",
        "value2": 0,
        "value3": true,
        "test": false
    },
    "field2": [
        "value"
    ],
    "files": [
        "this/is/my/path"
    ]
}
{
    "id": "my_id",
    "field1": {
        "value": true,
        "test": true
    },
    "target": {
        "value1": "value",
        "value2": 30,
        "value3": false,
        "test": false
    },
    "field2": [
        "value"
    ],
    "files": [
        "this/is/my/path"
    ]
}
{
    "id": "my_id",
    "field1": {
        "value": true,
        "test": true
    },
    "target": {
        "value1": "value",
        "value2": 10,
        "value3": true,
        "test": true
    },
    "field2": [
        "value"
    ],
    "files": [
        "this/is/my/path"
    ]
}

for each object, I’d like to extract the test field in target and files path.

To do that I try:

#[derive(Debug, Serialize, Deserialize)]
struct AllFiles {
    target: Target,
    files: Vec<String>
}

#[derive(Debug, Serialize, Deserialize)]
struct Target {
    test: bool
}

fn main() {
   let json = "JSON string above ^^^";
   let all_files: Vec<AllFiles> = serde_json::from_str(json).unwrap();
}

but I have this error: Error("invalid type: map, expected a sequence", line: 1, column: 0)'

I can’t figure out how to manage it.
At the end I want Vec so I can browse it and test each of its objects

can anyone help me with this problem?

2

Answers


  1. I’ve tried to reproduce your issue on the Rust Playground, ans this code runs correctly. I’m assuming your data is contained inside an array, and I’ve also changed the path strings to contain a number at the end for the purposes of better visualization of the results. You can try it here

    use serde::{Serialize, Deserialize};
    
    #[derive(Debug, Serialize, Deserialize)]
    struct AllFiles {
        target: Target,
        files: Vec<String>
    }
    
    #[derive(Debug, Serialize, Deserialize)]
    struct Target {
        test: bool
    }
    
    fn main() {
       let json = r#"[
       {
            "id": "my_id",
            "field1": {
                "value": true,
                "test": true
            },
            "target": {
                "value1": "value",
                "value2": 0,
                "value3": true,
                "test": false
            },
            "field2": [
                "value"
            ],
            "files": [
                "this/is/my/path1"
            ]
        },
        {
            "id": "my_id",
            "field1": {
                "value": true,
                "test": true
            },
            "target": {
                "value1": "value",
                "value2": 0,
                "value3": true,
                "test": false
            },
            "field2": [
                "value"
            ],
            "files": [
                "this/is/my/path2"
            ]
        },
        {
            "id": "my_id",
            "field1": {
                "value": true,
                "test": true
            },
            "target": {
                "value1": "value",
                "value2": 10,
                "value3": true,
                "test": true
            },
            "field2": [
                "value"
            ],
            "files": [
                "this/is/my/path3"
            ]
        }
        ]"#;
       let all_files: Vec<AllFiles> = serde_json::from_str(json).unwrap();
       
       for item in all_files {
           println!("{:?}", item);
       }
    }
    
    Login or Signup to reply.
  2. The data, as it’s currently in your post, contains multiple JSON values. To parse, you’ll need a serde_json::StreamDeserializer, which you can construct with serde_json::Deserializer::into_iter:

    let all_files = serde_json::Deserializer::from_str(json)
        .into_iter()
        .collect::<Result<Vec<AllFiles>, _>>();
    

    The details are in the serde_json docs.

    Playground

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search