Serde_json: checking syntax of JSON file

I want to check the syntax of a JSON file not caring about the content of the JSON file.

Here a first minimal example to try serde_json:

extern crate serde_json;

fn main() {
    let s = "{}"; // valid JSON

    serde_json::from_str(&s).unwrap_or_else(|e| {
        eprintln!("Json: '{}'\nError: {}",s, e);
        ::std::process::exit(1);
    })
}

which gives:

Json: '{}'
Error: invalid type: map, expected unit at line 1 column 0

Any idea what I'm doing wrong?

1 Like

When you use serde_json::from_str() it'll try to infer the type to parse your string into. You forgot a semicolon at the end of the line and because main doesn't return anything (i.e. it returns ()) we try to deserialize into the unit value. I'm not exactly sure what this is in JSON.

If you don't actually care what type it deserializes as, just that you can deserializes it, look at the serde_json::Value type. This is essentially a union of all the possible things JSON can represent.

Aaah, thanks.

This is working now:

extern crate serde_json;

fn main() {
    let s = "{}"; // valid JSON

    let _:serde_json::Value = serde_json::from_str(&s).unwrap_or_else(|e| {
        eprintln!("Json: '{}'\nError: {}",s, e);
        ::std::process::exit(1);
    });
    println!("Ok");
}

I haven't done any measurements, but using IgnoredAny should be a more efficient way to do this check:

extern crate serde;
extern crate serde_json;

fn main() {
    let s = r##"{"r": 1, "s": [1, 2, 3]}"##; // valid JSON

    let _: serde::de::IgnoredAny = serde_json::from_str(&s).unwrap_or_else(|e| {
        eprintln!("Json: '{}'\nError: {}",s, e);
        ::std::process::exit(1);
    });
    println!("Ok");
}

It still checks the json syntax, but it doesn't construct any json value.

1 Like

I didn't know about this. Thanks a lot.

It saves a lot of time. Before it took 1.54 secs to parse an 100 MB file. Now it takes 0.44 secs to parse the same file.

Thanks again, Manfred

2 Likes