Skip to content

Commit

Permalink
📝 overwork documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
nlohmann committed Jan 9, 2022
1 parent 6d8d043 commit ef55601
Show file tree
Hide file tree
Showing 7 changed files with 267 additions and 124 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ Linear.
--8<-- "examples/operator_literal_json_pointer.output"
```

## See also

- [json_pointer](../json_pointer/index.md) - type to represent JSON Pointers

## Version history

- Added in version 2.0.0.
1 change: 1 addition & 0 deletions doc/mkdocs/docs/api/json_pointer/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ are the base for JSON patches.

## See also

- [operator""_json_pointer](../basic_json/operator_literal_json_pointer.md) - user-defined string literal for JSON pointers
- [RFC 6901](https://datatracker.ietf.org/doc/html/rfc6901)

## Version history
Expand Down
124 changes: 114 additions & 10 deletions doc/mkdocs/docs/features/json_pointer.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,123 @@
# JSON Pointer

The library supports **JSON Pointer** ([RFC 6901](https://tools.ietf.org/html/rfc6901)) as alternative means to address structured values.
## Introduction

The library supports **JSON Pointer** ([RFC 6901](https://tools.ietf.org/html/rfc6901)) as alternative means to address
structured values. A JSON Pointer is a string that identifies a specific value withing a JSON document.

Consider the following JSON document

```json
{
"array": ["A", "B", "C"],
"nested": {
"one": 1,
"two": 2,
"three": [true, false]
}
}
```

Then every value inside the JSON document can be idientified as follows:

| JSON Pointer | JSON value |
|-------------------|----------------------------------------------------------------------------------|
| `/` | `#!json {"array":["A","B","C"],"nested":{"one":1,"two":2,"three":[true,false]}}` |
| `/array` | `#!json ["A","B","C"]` |
| `/array/0` | `#!json A` |
| `/array/1` | `#!json B` |
| `/array/2` | `#!json C` |
| `/nested` | `#!json {"one":1,"two":2,"three":[true,false]}` |
| `/nested/one` | `#!json 1` |
| `/nested/two` | `#!json 2` |
| `/nested/three` | `#!json [true,false]` |
| `/nested/three/0` | `#!json true` |
| `/nested/three/1` | `#!json false` |

## JSON Pointer creation

JSON Pointers can be created from a string:

```cpp
json::json_pointer p = "/nested/one";
```

Furthermore, a user-defined string literal can be used to achieve the same result:

```cpp
auto p = "/nested/one"_json_pointer;
```

The escaping rules of [RFC 6901](https://tools.ietf.org/html/rfc6901) are implemented. See the
[constructor documentation](../api/json_pointer/json_pointer.md) for more information.

## Value access

JSON Pointers can be used in the [`at`](../api/basic_json/at.md), [`operator[]`](../api/basic_json/operator%5B%5D.md),
and [`value`](../api/basic_json/value.md) functions just like object keys or array indices.

```cpp
// the JSON value from above
auto j = json::parse(R"({
"array": ["A", "B", "C"],
"nested": {
"one": 1,
"two": 2,
"three": [true, false]
}
})");

// access values
auto val = j["/"_json_pointer]; // {"array":["A","B","C"],...}
auto val1 = j["/nested/one"_json_pointer]; // 1
auto val2 = j.at[json::json_pointer("/nested/three/1")]; // false
auto val3 = j.value[json::json_pointer("/nested/four", 0)]; // 0
```

## Flatten / unflatten

The library implements a function [`flatten`](../api/basic_json/flatten.md) to convert any JSON document into a JSON
object where each key is a JSON Pointer and each value is a primitive JSON value (i.e., a string, boolean, number, or
null).

```cpp
// the JSON value from above
auto j = json::parse(R"({
"array": ["A", "B", "C"],
"nested": {
"one": 1,
"two": 2,
"three": [true, false]
}
})");

// create flattened value
auto j_flat = j.flatten();
```

The resulting value `j_flat` is:

```json
{
"/array/0": "A",
"/array/1": "B",
"/array/2": "C",
"/nested/one": 1,
"/nested/two": 2,
"/nested/three/0": true,
"/nested/three/1": false
}
```

The reverse function, [`unflatten`](../api/basic_json/unflatten.md) recreates the original value.

```cpp
// a JSON value
json j_original = R"({
"baz": ["one", "two", "three"],
"foo": "bar"
})"_json;

// access members with a JSON pointer (RFC 6901)
j_original["/baz/1"_json_pointer];
// "two"
auto j_original = j_flat.unflatten();
```

## See also

- Class [`json_pointer`](../api/json_pointer/index.md)
- Function [`flatten`](../api/basic_json/flatten.md)
- Function [`unflatten`](../api/basic_json/unflatten.md)
- [JSON Patch](json_patch.md)
176 changes: 99 additions & 77 deletions doc/mkdocs/docs/integration/cmake.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,102 +2,124 @@

## Integration

You can also use the `nlohmann_json::nlohmann_json` interface target in CMake. This target populates the appropriate usage requirements for `INTERFACE_INCLUDE_DIRECTORIES` to point to the appropriate include directories and `INTERFACE_COMPILE_FEATURES` for the necessary C++11 flags.
You can use the `nlohmann_json::nlohmann_json` interface target in CMake. This target populates the appropriate usage
requirements for [`INTERFACE_INCLUDE_DIRECTORIES`](https://cmake.org/cmake/help/latest/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES.html)
to point to the appropriate include directories and [`INTERFACE_COMPILE_FEATURES`](https://cmake.org/cmake/help/latest/prop_tgt/INTERFACE_COMPILE_FEATURES.html)
for the necessary C++11 flags.

### External

To use this library from a CMake project, you can locate it directly with `find_package()` and use the namespaced imported target from the generated package configuration:
To use this library from a CMake project, you can locate it directly with [`find_package()`](https://cmake.org/cmake/help/latest/command/find_package.html)
and use the namespaced imported target from the generated package configuration:

```cmake
# CMakeLists.txt
find_package(nlohmann_json 3.2.0 REQUIRED)
...
add_library(foo ...)
...
target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
```
!!! example

The package configuration file, `nlohmann_jsonConfig.cmake`, can be used either from an install tree or directly out of the build tree.
```cmake title="CMakeLists.txt"
cmake_minimum_required(VERSION 3.1)
project(ExampleProject LANGUAGES CXX)

find_package(nlohmann_json 3.10.5 REQUIRED)

add_executable(example example.cpp)
target_link_libraries(example PRIVATE nlohmann_json::nlohmann_json)
```

The package configuration file, `nlohmann_jsonConfig.cmake`, can be used either from an install tree or directly out of
the build tree.

### Embedded

To embed the library directly into an existing CMake project, place the entire source tree in a subdirectory and call `add_subdirectory()` in your `CMakeLists.txt` file:
To embed the library directly into an existing CMake project, place the entire source tree in a subdirectory and call
`add_subdirectory()` in your `CMakeLists.txt` file.

```cmake
# If you only include this third party in PRIVATE source files, you do not
# need to install it when your main project gets installed.
# set(JSON_Install OFF CACHE INTERNAL "")
!!! example

# Don't use include(nlohmann_json/CMakeLists.txt) since that carries with it
# unintended consequences that will break the build. It's generally
# discouraged (although not necessarily well documented as such) to use
# include(...) for pulling in other CMake projects anyways.
add_subdirectory(nlohmann_json)
...
add_library(foo ...)
...
target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
```
```cmake title="CMakeLists.txt"
cmake_minimum_required(VERSION 3.1)
project(ExampleProject LANGUAGES CXX)

### Embedded (FetchContent)
# If you only include this third party in PRIVATE source files, you do not need to install it
# when your main project gets installed.
set(JSON_Install OFF CACHE INTERNAL "")

add_subdirectory(nlohmann_json)

Since CMake v3.11,
[FetchContent](https://cmake.org/cmake/help/v3.11/module/FetchContent.html) can
be used to automatically download the repository as a dependency at configure type.
add_executable(example example.cpp)
target_link_libraries(example PRIVATE nlohmann_json::nlohmann_json)
```

Example:
```cmake
include(FetchContent)
!!! note

FetchContent_Declare(json
GIT_REPOSITORY https://github.com/nlohmann/json
GIT_TAG v3.7.3)
Do not use `#!cmake include(nlohmann_json/CMakeLists.txt)`, since that carries with it unintended consequences that
will break the build. It is generally discouraged (although not necessarily well documented as such) to use
`#!cmake include(...)` for pulling in other CMake projects anyways.

FetchContent_GetProperties(json)
if(NOT json_POPULATED)
FetchContent_Populate(json)
add_subdirectory(${json_SOURCE_DIR} ${json_BINARY_DIR} EXCLUDE_FROM_ALL)
endif()

target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
```
### Supporting Both

!!! Note
The repository <https://github.com/nlohmann/json> download size is quite large.
You might want to depend on a smaller repository. For instance, you might want to replace the URL above by
<https://github.com/ArthurSonzogni/nlohmann_json_cmake_fetchcontent>.
To allow your project to support either an externally supplied or an embedded JSON library, you can use a pattern akin
to the following.

### Supporting Both
!!! example

```cmake title="CMakeLists.txt"
project(ExampleProject LANGUAGES CXX)

option(EXAMPLE_USE_EXTERNAL_JSON "Use an external JSON library" OFF)

add_subdirectory(thirdparty)

add_executable(example example.cpp)

# Note that the namespaced target will always be available regardless of the import method
target_link_libraries(example PRIVATE nlohmann_json::nlohmann_json)
```

```cmake title="thirdparty/CMakeLists.txt"
if(EXAMPLE_USE_EXTERNAL_JSON)
find_package(nlohmann_json 3.10.5 REQUIRED)
else()
set(JSON_BuildTests OFF CACHE INTERNAL "")
add_subdirectory(nlohmann_json)
endif()
```

`thirdparty/nlohmann_json` is then a complete copy of this source tree.


### FetchContent

Since CMake v3.11, [FetchContent](https://cmake.org/cmake/help/v3.11/module/FetchContent.html) can be used to
automatically download the repository as a dependency at configure type.

!!! example

```cmake title="CMakeLists.txt"
cmake_minimum_required(VERSION 3.11)
project(ExampleProject LANGUAGES CXX)

include(FetchContent)

FetchContent_Declare(json
GIT_REPOSITORY https://github.com/nlohmann/json
GIT_TAG v3.10.5
)

FetchContent_GetProperties(json)
if(NOT json_POPULATED)
FetchContent_Populate(json)
add_subdirectory(${json_SOURCE_DIR} ${json_BINARY_DIR} EXCLUDE_FROM_ALL)
endif()

add_executable(example example.cpp)
target_link_libraries(example PRIVATE nlohmann_json::nlohmann_json)
```

!!! Note

To allow your project to support either an externally supplied or an embedded JSON library, you can use a pattern akin to the following:

``` cmake
# Top level CMakeLists.txt
project(FOO)
...
option(FOO_USE_EXTERNAL_JSON "Use an external JSON library" OFF)
...
add_subdirectory(thirdparty)
...
add_library(foo ...)
...
# Note that the namespaced target will always be available regardless of the
# import method
target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
```
```cmake
# thirdparty/CMakeLists.txt
...
if(FOO_USE_EXTERNAL_JSON)
find_package(nlohmann_json 3.2.0 REQUIRED)
else()
set(JSON_BuildTests OFF CACHE INTERNAL "")
add_subdirectory(nlohmann_json)
endif()
...
```

`thirdparty/nlohmann_json` is then a complete copy of this source tree.
The repository <https://github.com/nlohmann/json> download size is quite large. You might want to depend on a
smaller repository. For instance, you might want to replace the URL in the example by
<https://github.com/ArthurSonzogni/nlohmann_json_cmake_fetchcontent>.

## CMake Options

Expand Down
3 changes: 2 additions & 1 deletion doc/mkdocs/docs/integration/example.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#include <nlohmann/json.hpp>
#include <iostream>
#include <iomanip>

using json = nlohmann::json;

int main()
{
std::cout << json::meta() << std::endl;
std::cout << std::setw(4) << json::meta() << std::endl;
}
10 changes: 7 additions & 3 deletions doc/mkdocs/docs/integration/index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Header only

[`json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp) is the single required file in `single_include/nlohmann` or [released here](https://github.com/nlohmann/json/releases). You need to add
[`json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp) is the single required
file in `single_include/nlohmann` or [released here](https://github.com/nlohmann/json/releases). You need to add

```cpp
#include <nlohmann/json.hpp>
Expand All @@ -9,6 +10,9 @@
using json = nlohmann::json;
```

to the files you want to process JSON and set the necessary switches to enable C++11 (e.g., `-std=c++11` for GCC and Clang).
to the files you want to process JSON and set the necessary switches to enable C++11 (e.g., `-std=c++11` for GCC and
Clang).

You can further use file [`include/nlohmann/json_fwd.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/json_fwd.hpp) for forward-declarations. The installation of `json_fwd.hpp` (as part of CMake's install step), can be achieved by setting `-DJSON_MultipleHeaders=ON`.
You can further use file [`include/nlohmann/json_fwd.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/json_fwd.hpp)
for forward-declarations. The installation of `json_fwd.hpp` (as part of CMake's install step), can be achieved by
setting `-DJSON_MultipleHeaders=ON`.
Loading

0 comments on commit ef55601

Please sign in to comment.