Skip to content

Latest commit

 

History

History
151 lines (106 loc) · 4.27 KB

README.md

File metadata and controls

151 lines (106 loc) · 4.27 KB

JSONC

JSONC is a lightweight implementation of JSON Data Interchange Standard for C++ programming language.

It is an ideal candidate to use with microcontrollers. The library was tested with Raspberry Pi Pico and Pico W.

JSON + C++ = ❤️

Add dependency

CMake

CMake provides a convenient way to depend on the library.

include(FetchContent)

FetchContent_Declare(
  JSONC
  GIT_REPOSITORY git@github.com:st235/JSONC.git
  GIT_TAG "main"
  GIT_SHALLOW TRUE
  GIT_PROGRESS ON
)
FetchContent_MakeAvailable(JSONC)

target_link_libraries(your-project-target jsonc)

Check out samples for more.

Exploring the API

Almost everything you might expect has been implemented. Take a look at this real-life example:

  if (response.isObject() && response["results"].isArray()) {
      const auto& results_array = response["results"].asArray();

      for (size_t i = 0; i < results_array.size(); i++) {
          const auto& raw_character = results_array[i];

          Character c = {
              uint32_t(raw_character["id"].asNumber()),
              raw_character["name"].asString(),
              raw_character["species"].asString(),
              raw_character["gender"].asString(),
              raw_character["image"].asString()
          };

          ...
      }
  }

Here are a few more examples of the most common use cases for your reference.

Create Json object from a string

std::string json_text = ...
const auto& json = json::Json::fromJson(json_text);

Declare Json object and dump it to back to string

json::Json json = { 
  std::make_pair("a", json::Json({ json::Json(true), json::Json("b") })),
  std::make_pair("b", json::Json(129.1))
};

std::string json_text = json::Json::toString(json);

In this example, the json object will be minified. If you want to beautify the JSON (i.e., make it human-readable), the library offers a default implementation of JsonBeautifier, which you can find in the samples folder.

Types

The following paragraphs provide a deep dive into the implementation details of the library.

JSON specification declares 4 types and 3 literals:

  • Literals
    • null
    • true
    • false
  • Types
    • number
    • string
    • array
    • object

All json values are conform to specially defined json::Json type. To check for those literals and types Json defines special boolean methods:

  • Json#isNull
  • Json#isBool
  • Json#isNumber
  • Json#isString
  • Json#isArray
  • Json#isObject

Almost all is methods (except isNull) has corresponding as methods to safely get the content of json file:

  • asBool -> returns bool
  • asNumber -> double
  • asString -> std::string
  • asArray -> std::vector<Json>
  • asObject -> std::unordered_map<std::string, Json>

Json Grammar Rules

The specification of JSON format is available at the oficial website or as ECMA-404 The JSON Data Interchange Standard.

The grammar specifies 6 entries: array, number, object, string, value, and whitespace. value is the entry point.

I won't cover all the details of the implemention but will provide the most important grammar rules.

Array Number Object
Array Number Object
String Value Whitespace
String Value Whitespace

Contribution

The project is using CMake as the build system.

Building

Use these commands to build the project:

mkdir build
cmake .. -DCOMPILE_TESTS=ON -DASSERT=ON
make

ASSERT=ON is used to enabled assertions in the codebase. If you're building a release flavour then you may consider to do not specify this setting.

Running test

A lot of logic in the library heavily relies on unit and integration tests. To run them you need yo successfully build the project and run the command below:

ctest --output-on-failure