A easy and declarative way to test JSON input in Rust.

Overview

assert_json

ci Crates.io docs.rs

A easy and declarative way to test JSON input in Rust. assert_json is a Rust macro heavily inspired by serde json macro. Instead of creating a JSON value from a JSON literal, assert_json makes sure the JSON input conforms to the validation rules specified.

assert_json also output beautiful error message when a validation error occurs.

How to use

0 { Ok(())} else { Err(String::from("id should be greater than 0")) }), "name": name, } } ); } ">
use assert_json::assert_json;
use assert_json::validators;

#[test]
fn test_json_ok() {
    let json = r#"
        {
            "status": "success",
            "result": {
                "id": 5,
                "name": "charlesvdv"
            }
        }
    "#;

    let name = "charlesvdv";

    assert_json!(json, {
            "status": "success",
            "result": {
                "id": validators::u64(|&v| if v > 0 { Ok(())} else { Err(String::from("id should be greater than 0")) }),
                "name": name,
            }
        }
    );
}

Any variables or expressions are interpoled as validation rules matching the type and value of the variable/expression passed to the macro.

Now, if JSON input is changed to something incorrect like this:

    let json = r#"
        {
            "status": "success",
            "result": {
                "id": 5,
-                "name": "charlesvdv"
+                "name": "incorrect name"
            }
        }
    "#;

You will get an comprehensible error message like this one:

thread 'xxxx' panicked at 'error: Invalid JSON
  ┌─ :4:17
  │
4 │         "name": "incorrect name"
  │                 ^^^^^^^^^^^^^^^^ Invalid value. Expected "charlesvdv" but got "incorrect name".

Custom validators

A set of validators are already implemented in the validators module. If required, one can also creates its own validation routine by implementing the Validator trait.

use assert_json::{assert_json, Error, Validator, Value};

fn optional_string(expected: Option<String>) -> impl Validator {
    OptionalStringValidator { expected }
}

/// Matches a null JSON value if expected is None, else check if the strings
/// are equals
struct OptionalStringValidator {
    expected: Option<String>,
}

impl Validator for OptionalStringValidator {
    fn validate<'a>(&self, value: &'a Value) -> Result<(), Error<'a>> {
        if let Some(expected_str) = &self.expected {
            let string_value = value
                .as_str()
                .ok_or_else(|| Error::InvalidType(value, String::from("string")))?;

            if expected_str == string_value {
                Ok(())
            } else {
                Err(Error::InvalidValue(value, expected_str.clone()))
            }
        } else {
            value.as_null()
                .ok_or_else(|| Error::InvalidType(value, String::from("null")))
        }
    }
}

let json = r#"
    {
        "key": "value",
        "none": null
    }
"#;
assert_json!(json, {
    "key": optional_string(Some(String::from("value"))),
    "none": optional_string(None),
});

Alternatives

Acknowledgments

Thanks a lot to the serde-rs/json project members and especially those who contributed to the json! macro.

You might also like...
A rust script to convert a better bibtex json file from Zotero into nice organised notes in Obsidian

Zotero to Obsidian script This is a script that takes a better bibtex JSON file exported by Zotero and generates an organised collection of reference

CLI tool to convert HOCON into valid JSON or YAML written in Rust.

{hocon:vert} CLI Tool to convert HOCON into valid JSON or YAML. Under normal circumstances this is mostly not needed because hocon configs are parsed

Typify - Compile JSON Schema documents into Rust types.

Typify Compile JSON Schema documents into Rust types. This can be used ... via the macro import_types!("types.json") to generate Rust types directly i

A small rust database that uses json in memory.

Tiny Query Database (TQDB) TQDB is a small library for creating a query-able database that is encoded with json. The library is well tested (~96.30% c

A JSON Query Language CLI tool built with Rust 🦀

JQL A JSON Query Language CLI tool built with Rust 🦀 📜 Core philosophy 📦 Stay lightweight 🎮 Keep its features as simple as possible 🧠 Avoid redun

rurl is like curl but with a json configuration file per request

rurl rurl is a curl-like cli tool made in rust, the difference is that it takes its params from a json file so you can have all different requests sav

A tool for outputs semantic difference of json

jsondiff A tool for outputs semantic difference of json. "semantic" means: sort object key before comparison sort array before comparison (optional, b

Easily create dynamic css using json notation

jss! This crate provides an easy way to write dynamic css using json notation. This gives you more convenient than you think. Considering using a dyna

Decode Metaplex mint account metadata into a JSON file.

Simple Metaplex Decoder (WIP) Install From Source Install Rust. curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh Clone the source: git c

Comments
  • array_contains asserts elements are present in input

    array_contains asserts elements are present in input

    I find that I frequently want to assert that an array contains at least certain elements. This validator asserts that each sub validator matches a unique element in an array. This is inspired by Jest's arrayContaining. Making this validator print detailed info on failure is a challenge since validators do not implement Display; unlike other validators, it is unordered and cannot know what element a specific sub-validator is supposed to match. Right now it uses the validator's position to say:

    thread 'validators::array::tests::message' panicked at 'error: Invalid JSON
      ┌─ :1:1
      │
    1 │ ╭ [
    2 │ │     3,
    3 │ │     1
    4 │ │ ]
      │ ╰─^ No match for expected array element 1
    
    opened by bittrance 0
Owner
Charles Vandevoorde
Software engineer from Brussels . Passionate about software engineering. Love open-source. Sometimes, I develop side-projects.
Charles Vandevoorde
Get JSON values quickly - JSON parser for Rust

get json values quickly GJSON is a Rust crate that provides a fast and simple way to get values from a json document. It has features such as one line

Josh Baker 160 Dec 29, 2022
Read and write ID3 tags with machine-readable input and output

ID3-JSON This project's goal is to provide an easy way to read and write ID3 tags with a consistent input and output. The existing tools I've found re

Andrew Radev 4 Jan 7, 2023
Jsonptr - Data structures and logic for resolving, assigning, and deleting by JSON Pointers

jsonptr - JSON Pointers for Rust Data structures and logic for resolving, assigning, and deleting by JSON Pointers (RFC 6901). Usage Resolve JSON Poin

Chance 38 Aug 28, 2022
A fast and simple command-line tool for common operations over JSON-lines files

rjp: Rapid JSON-lines processor A fast and simple command-line tool for common operations over JSON-lines files, such as: converting to and from text

Ales Tamchyna 3 Jul 8, 2022
Converts cargo check (and clippy) JSON output to the GitHub Action error format

cargo-action-fmt Takes JSON-formatted cargo check (and cargo clippy) output and formats it for GitHub actions. Examples This tool can be used with a v

Oliver Gould 8 Oct 12, 2022
Esri JSON struct definitions and serde integration.

serde_esri Esri JSON parsing library. This crate provides representations of Esri JSON objects with serde::Deserialize and serde::Serialize trait impl

Josiah Parry 5 Nov 23, 2023
JSON parser which picks up values directly without performing tokenization in Rust

Pikkr JSON parser which picks up values directly without performing tokenization in Rust Abstract Pikkr is a JSON parser which picks up values directl

Pikkr 615 Dec 29, 2022
Strongly typed JSON library for Rust

Serde JSON   Serde is a framework for serializing and deserializing Rust data structures efficiently and generically. [dependencies] serde_json = "1.0

null 3.6k Jan 5, 2023
JSON implementation in Rust

json-rust Parse and serialize JSON with ease. Changelog - Complete Documentation - Cargo - Repository Why? JSON is a very loose format where anything

Maciej Hirsz 500 Dec 21, 2022
Rust port of gjson,get JSON value by dotpath syntax

A-JSON Read JSON values quickly - Rust JSON Parser change name to AJSON, see issue Inspiration comes from gjson in golang Installation Add it to your

Chen Jiaju 90 Dec 6, 2022