1 unstable release

0.1.0 Feb 2, 2023

#1153 in Encoding

Download history 2028/week @ 2023-12-11 2817/week @ 2023-12-18 393/week @ 2023-12-25 250/week @ 2024-01-01 516/week @ 2024-01-08 744/week @ 2024-01-15 1756/week @ 2024-01-22 1477/week @ 2024-01-29 1450/week @ 2024-02-05 1002/week @ 2024-02-12 534/week @ 2024-02-19 2361/week @ 2024-02-26 2114/week @ 2024-03-04 1655/week @ 2024-03-11 1232/week @ 2024-03-18 2689/week @ 2024-03-25

9,010 downloads per month
Used in 4 crates

Apache-2.0

72KB
2K SLoC

JSON5

A Rust library for serializing and deserializing JSON5 with Serde.

This project is a fork of callum-oakley/json5-rs.


lib.rs:

JSON5 is a superset of JSON with an expanded syntax including some productions from ECMAScript 5.1.

In particular, JSON5 allows comments, trailing commas, object keys without quotes, single quoted strings and more. See the JSON5 project page for full details.

{
  // comments
  unquoted: 'and you can quote me on that',
  singleQuotes: 'I can use "double quotes" here',
  lineBreaks: "Look, Mom! \
No \\n's!",
  hexadecimal: 0xdecaf,
  leadingDecimalPoint: .8675309, andTrailing: 8675309.,
  positiveSign: +1,
  trailingComma: 'in objects', andIn: ['arrays',],
  "backwardsCompatible": "with JSON",
}

This crate provides functions for deserializing JSON5 text into a Rust datatype and for serializing a Rust datatype as JSON5 text, both via the Serde framework.

Deserialization

Implementing Serde’s Deserialize trait on your type will allow you to parse JSON5 text into a value of that type with from_str.

use serde_derive::Deserialize;

#[derive(Deserialize, Debug, PartialEq)]
struct Config {
    message: String,
    n: i32,
}

let config = "
    {
      // A traditional message.
      message: 'hello world',

      // A number for some reason.
      n: 42,
    }
";

assert_eq!(
    serde_json5::from_str(config),
    Ok(Config {
        message: "hello world".to_string(),
        n: 42,
    }),
);

There are many ways to customise the deserialization (e.g. deserializing camelCase field names into a struct with snake_case fields). See the Serde docs, especially the Attributes, Custom serialization and Examples sections.

Serialization

Similarly, implementing Serialize on a Rust type allows you to produce a JSON5 serialization of values of that type with to_string. At present the serializer will just produce JSON (since it's a valid subset of JSON5), but future work will allow specifying the output style (single over double quotes, trailing commas, indentation etc.).

use serde_derive::Serialize;

#[derive(Serialize, PartialEq, Debug)]
#[serde(untagged)]
enum Val {
    Number(f64),
    Bool(bool),
    String(String),
}

assert_eq!(
    serde_json5::to_string(&vec![
        Val::Number(42.),
        Val::Bool(true),
        Val::String("hello".to_owned()),
    ]),
    Ok("[42,true,\"hello\"]".to_owned()),
)

There are many ways to customise the serialization (e.g. serializing snake_case struct fields as camelCase). See the Serde docs, especially the Attributes, Custom serialization and Examples sections.

Limitations

At the time of writing the following is unsupported:

  • deserializing into borrowed types (e.g. fields of type &str)

  • serializing or deserializing byte arrays

  • specifying the style of JSON5 output from the serializer (single over double quotes, trailing commas, indentation etc.)

Dependencies

~2.3–3MB
~65K SLoC