Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add migration guide #3887

Merged
merged 1 commit into from
Dec 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/docset/docSet.sql
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ INSERT INTO searchIndex(name, type, path) VALUES ('Element Access', 'Guide', 'fe
INSERT INTO searchIndex(name, type, path) VALUES ('Element Access: Access with default value: value', 'Guide', 'features/element_access/default_value/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Element Access: Checked access: at', 'Guide', 'features/element_access/checked_access/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Element Access: Unchecked access: operator[]', 'Guide', 'features/element_access/unchecked_access/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Integration: Migration Guide', 'Guide', 'integration/migration_guide/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Integration: CMake', 'Guide', 'integration/cmake/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Integration: Header only', 'Guide', 'integration/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Integration: Package Managers', 'Guide', 'integration/package_managers/index.html');
Expand Down
264 changes: 264 additions & 0 deletions docs/mkdocs/docs/integration/migration_guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
# Migration Guide

This page collects some guidelines on how to future-proof your code for future versions of this library.

## Replace deprecated functions

The following functions have been deprecated and will be removed in the next major version (i.e., 4.0.0). All
deprecations are annotated with
[`HEDLEY_DEPRECATED_FOR`](https://nemequ.github.io/hedley/api-reference.html#HEDLEY_DEPRECATED_FOR) to report which
function to use instead.

#### Parsing

- Function `friend std::istream& operator<<(basic_json&, std::istream&)` is deprecated since 3.0.0. Please use
[`friend std::istream& operator>>(std::istream&, basic_json&)`](../api/operator_gtgt.md) instead.

=== "Deprecated"

```cpp
nlohmann::json j;
std::stringstream ss("[1,2,3]");
j << ss;
```

=== "Future-proof"

```cpp
nlohmann::json j;
std::stringstream ss("[1,2,3]");
ss >> j;
```

- Passing iterator pairs or pointer/length pairs to parsing functions ([`parse`](../api/basic_json/parse.md),
[`accept`](../api/basic_json/accept.md), [`sax_parse`](../api/basic_json/sax_parse.md),
[`from_cbor`](../api/basic_json/from_cbor.md), [`from_msgpack`](../api/basic_json/from_msgpack.md),
[`from_ubjson`](../api/basic_json/from_ubjson.md), and [`from_bson`](../api/basic_json/from_bson.md) via initializer
lists is deprecated since 3.8.0. Instead, pass two iterators; for instance, call `from_cbor(ptr, ptr+len)` instead of
`from_cbor({ptr, len})`.

=== "Deprecated"

```cpp
const char* s = "[1,2,3]";
bool ok = nlohmann::json::accept({s, s + std::strlen(s)});
```

=== "Future-proof"

```cpp
const char* s = "[1,2,3]";
bool ok = nlohmann::json::accept(s, s + std::strlen(s));
```

#### JSON Pointers

- Comparing JSON Pointers with strings via [`operator==`](../api/json_pointer/operator_eq.md) and
[`operator!=`](../api/json_pointer/operator_ne.md) is deprecated since 3.11.2. To compare a
[`json_pointer`](../api/json_pointer/index.md) `p` with a string `s`, convert `s` to a `json_pointer` first and use
[`json_pointer::operator==`](../api/json_pointer/operator_eq.md) or
[`json_pointer::operator!=`](../api/json_pointer/operator_ne.md).

=== "Deprecated"

```cpp
nlohmann::json::json_pointer lhs("/foo/bar/1");
assert(lhs == "/foo/bar/1");
```

=== "Future-proof"

```cpp
nlohmann::json::json_pointer lhs("/foo/bar/1");
assert(lhs == nlohmann::json::json_pointer("/foo/bar/1"));
```

- The implicit conversion from JSON Pointers to string
([`json_pointer::operator string_t`](../api/json_pointer/operator_string_t.md)) is deprecated since 3.11.0. Use
[`json_pointer::to_string`](../api/json_pointer/to_string.md) instead.

=== "Deprecated"

```cpp
nlohmann::json::json_pointer ptr("/foo/bar/1");
std::string s = ptr;
```

=== "Future-proof"

```cpp
nlohmann::json::json_pointer ptr("/foo/bar/1");
std::string s = ptr.to_string();
```

- Passing a `basic_json` specialization as template parameter `RefStringType` to
[`json_pointer`](../api/json_pointer/index.md) is deprecated since 3.11.0. The string type can now be directly
provided.

=== "Deprecated"

```cpp
using my_json = nlohmann::basic_json<std::map, std::vector, my_string_type>;
nlohmann::json_pointer<my_json> ptr("/foo/bar/1");
```

=== "Future-proof"

```cpp
nlohmann::json_pointer<my_string_type> ptr("/foo/bar/1");
```

Thereby, `nlohmann::my_json::json_pointer` is an alias for `nlohmann::json_pointer<my_string_type>` and is always an
alias to the `json_pointer` with the appropriate string type for all specializations of `basic_json`.

#### Miscellaneous functions

- The function `iterator_wrapper` is deprecated since 3.1.0. Please use the member function
[`items`](../api/basic_json/items.md) instead.

=== "Deprecated"

```cpp
for (auto &x : nlohmann::json::iterator_wrapper(j))
{
std::cout << x.key() << ":" << x.value() << std::endl;
}
```

=== "Future-proof"

```cpp
for (auto &x : j.items())
{
std::cout << x.key() << ":" << x.value() << std::endl;
}
```

- Function `friend std::ostream& operator>>(const basic_json&, std::ostream&)` is deprecated since 3.0.0. Please use
[`friend operator<<(std::ostream&, const basic_json&)`](../api/operator_ltlt.md) instead.

=== "Deprecated"

```cpp
j >> std::cout;
```

=== "Future-proof"

```cpp
std::cout << j;
```

- The legacy comparison behavior for discarded values is deprecated since 3.11.0. It is already disabled by default and
can still be enabled by defining
[`JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON`](../api/macros/json_use_legacy_discarded_value_comparison.md) to `1`.

=== "Deprecated"

```cpp
#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 1
#include <nlohmann/json.hpp>
```

=== "Future-proof"

```cpp
#include <nlohmann/json.hpp>
```

## Replace implicit conversions

Implicit conversions via [`operator ValueType`](../api/basic_json/operator_ValueType.md) will be switched off by default
in the next major release of the library.

You can prepare existing code by already defining
[`JSON_USE_IMPLICIT_CONVERSIONS`](../api/macros/json_use_implicit_conversions.md) to `0` and replace any implicit
conversions with calls to [`get`](../api/basic_json/get.md), [`get_to`](../api/basic_json/get_to.md),
[`get_ref`](../api/basic_json/get_ref.md), or [`get_ptr`](../api/basic_json/get_ptr.md).

=== "Deprecated"

```cpp
nlohmann::json j = "Hello, world!";
std::string s = j;
```

=== "Future-proof"

```cpp
nlohmann::json j = "Hello, world!";
auto s = j.get<std::string>();
```

=== "Future-proof (alternative)"

```cpp
nlohmann::json j = "Hello, world!";
std::string s;
j.get_to(s);
```

You can prepare existing code by already defining
[`JSON_USE_IMPLICIT_CONVERSIONS`](../api/macros/json_use_implicit_conversions.md) to `0` and replace any implicit
conversions with calls to [`get`](../api/basic_json/get.md).

## Import namespace `literals` for UDLs

The user-defined string literals [`operator""_json`](../api/operator_literal_json.md) and
[`operator""_json_pointer`](../api/operator_literal_json_pointer.md) will be removed from the global namespace in the
next major release of the library.

=== "Deprecated"

```cpp
nlohmann::json j = "[1,2,3]"_json;
```

=== "Future-proof"

```cpp
using namespace nlohmann::literals;
nlohmann::json j = "[1,2,3]"_json;
```

To prepare existing code, define [`JSON_USE_GLOBAL_UDLS`](../api/macros/json_use_global_udls.md) to `0` and bring the
string literals into scope where needed.

## Do not hard-code the complete library namespace

The [`nlohmann` namespace](../features/namespace.md) contains a sub-namespace to avoid problems when different
versions or configurations of the library are used in the same project. Always use `nlohmann` as namespace or, when the
exact version and configuration is relevant, use macro
[`NLOHMANN_JSON_NAMESPACE`](../api/macros/nlohmann_json_namespace.md) to denote the namespace.

=== "Dangerous"

```cpp
void to_json(nlohmann::json_abi_v3_11_2::json& j, const person& p)
{
j["age"] = p.age;
}
```

=== "Future-proof"

```cpp
void to_json(nlohmann::json& j, const person& p)
{
j["age"] = p.age;
}
```

=== "Future-proof (alternative)"

```cpp
void to_json(NLOHMANN_JSON_NAMESPACE::json& j, const person& p)
{
j["age"] = p.age;
}
```

## Do not use the `details` namespace

The `details` namespace is not part of the public API of the library and can change in any version without announcement.
Do not rely on any function or type in the `details` namespace.
5 changes: 4 additions & 1 deletion docs/mkdocs/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ theme:
- navigation.tabs
- navigation.indexes
- navigation.top
- content.tabs.link

nav:
- Home:
Expand Down Expand Up @@ -87,6 +88,7 @@ nav:
- features/types/number_handling.md
- Integration:
- integration/index.md
- integration/migration_guide.md
- integration/cmake.md
- integration/package_managers.md
- integration/pkg-config.md
Expand Down Expand Up @@ -332,7 +334,8 @@ markdown_extensions:
- pymdownx.superfences
- pymdownx.tasklist:
custom_checkbox: true
- pymdownx.tabbed
- pymdownx.tabbed:
alternate_style: true
- pymdownx.tilde
- pymdownx.snippets:
base_path: docs
Expand Down