BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdljsn.h
Go to the documentation of this file.
1/// @file bdljsn.h
2///
3///
4/// @defgroup bdljsn Package bdljsn
5/// @brief Basic Development Library JSoN (bdljsn)
6/// @addtogroup bdl
7/// @{
8/// @addtogroup bdljsn
9/// [bdljsn]: group__bdljsn.html
10/// @{
11///
12/// # Purpose {#bdljsn-purpose}
13/// Provide a value-semantic JSON type and supporting utilities
14///
15/// # Mnemonic {#bdljsn-mnemonic}
16/// Basic Development Library JSoN (bdljsn)
17///
18/// # Description {#bdljsn-description}
19/// The 'bdljsn' package provides the 'bdljsn::Json' type, found in
20/// the @ref bdljsn_json component, which is a value-semantic representation of JSON
21/// data. This package also provides facilities for reading and writing
22/// 'bdljsn::Json' objects to JSON documents. 'bdljsn::Json' has close structural
23/// similarities to the JSON grammar itself, which looks like the following, at a
24/// high level:
25/// @code
26/// JSON ::= Object
27/// | Array
28/// | String
29/// | Number
30/// | Boolean
31/// | null
32/// @endcode
33/// Noting that the 'Object' and 'Array' alternatives can recursively contain
34/// 'JSON'. Just like this grammar, the value of a 'bdljsn::Json' object can be
35/// an object, array, string, number, boolean, or the null value. Objects and
36/// Arrays are represented by the 'bdljsn::JsonObject' and 'bdljsn::JsonArray'
37/// types, respectively, and are also provided by the @ref bdljsn_json component.
38/// 'bdljsn::JsonObject' is an associative container from strings to
39/// 'bdljsn::Json' objects, and 'bdljsn::JsonArray' is a sequence container with
40/// 'bdljsn::Json' elements. Strings and booleans are represented with the
41/// standard 'bsl::string' and 'bool' types. The singular "null" value is
42/// represented by the 'bdljsn::JsonNull' type, which has a single value like
43/// 'std::monostate'. Numbers are represented by the 'bdljsn::JsonNumber' type,
44/// which has facilities for storing any number that satisfies the JSON number
45/// grammar with arbitrary precision. It also provides operations for converting
46/// these arbitrary-precision numbers to common finite-precision number vocabulary
47/// types like 'int', 'double', and 'bdldfp::Decimal64', and detecting where
48/// overflow, underflow, and/or truncation would occur during conversion.
49///
50/// Though this package provides several types representing different kinds of
51/// JSON values, in general the 'bdljsn::Json' interface is rich enough to be the
52/// primary vocabulary type for working with JSON. For example, if the value
53/// stored in a 'bdljsn::Json' holds a JSON object, then you can use much of the
54/// associative container interface on the 'bdljsn::Json' object directly, e.g.,
55/// @code
56/// void getName(bsl::string *name, const bdljsn::Json& json)
57/// // Load to the specified 'name' the "name" member of the specified
58/// // 'json'. The behavior is undefined unless 'json' is a JSON object and
59/// // has a "name" member that is a string.
60/// {
61/// // First, verify that the 'json' is a JSON object, and not another
62/// // kind of value.
63/// assert(json.isObject());
64///
65/// // Then, we can use the subscript operator with string keys, just like a
66/// // map.
67/// *name = json["name"].theString();
68/// }
69/// @endcode
70/// Alternatively, if a 'bdljsn::Json' holds a JSON array, then we can use it like
71/// a sequence container,
72/// @code
73/// bool findWaldo(const bdljsn::Json& json)
74/// // Return 'true' if 'json' is an array that contains the string "waldo",
75/// // and return 'false' otherwise.
76/// {
77/// if (!json.isArray()) {
78/// return false; // RETURN
79/// }
80///
81/// for (bsl::size_t i = 0; i != json.size(); ++i) {
82/// const bdljsn::Json& element = json[i];
83///
84/// if (!element.isString()) {
85/// continue; // CONTINUE
86/// }
87///
88/// if (element.theString() == "waldo") {
89/// return true; // RETURN
90/// }
91/// }
92///
93/// return false;
94/// }
95/// @endcode
96/// For an example of constructing 'bdljsn::Json' objects, consider the use case
97/// where we have a simple representation of an organization chart, which we would
98/// like to convert to JSON for printing to standard output:
99/// @code
100/// struct Employee {
101/// // PUBLIC DATA
102/// int d_id;
103/// bsl::string d_firstName;
104/// bsl::string d_lastName;
105/// };
106///
107/// struct Team {
108/// // PUBLIC DATA
109/// Employee d_manager;
110/// bsl::vector<Employee> d_members;
111/// };
112/// @endcode
113/// We can define utility functions for converting these types to JSON:
114/// @code
115/// struct Utility {
116/// // CLASS METHODS
117/// static void toJson(bdljsn::Json *json, const Employee& employee)
118/// // Load to the specified 'json' the value of the specified 'employee'
119/// // converted to a JSON value.
120/// {
121/// bdljsn::Json& result = *json;
122///
123/// result.makeObject();
124///
125/// result["id"] = employee.d_id;
126/// result["firstName"] = employee.d_firstName;
127/// result["lastName"] = employee.d_lastName;
128/// }
129///
130/// static void toJson(bdljsn::Json *json, const Team& team)
131/// // Load to the specified 'json' the value of the specified 'team'
132/// // converted to a JSON value.
133/// {
134/// bdljsn::Json& result = *json;
135/// result.makeObject();
136///
137/// bdljsn::Json manager;
138/// toJson(&manager, team.d_manager);
139/// result["manager"] = bsl::move(manager);
140///
141/// bdljsn::Json members;
142/// members.makeArray();
143/// for (bsl::size_t i = 0; i != team.d_members.size(); ++i) {
144/// bdljsn::Json member;
145/// toJson(&member, team.d_members[i]);
146/// members[i] = bsl::move(member);
147/// }
148/// result["members"] = bsl::move(members);
149/// }
150/// };
151/// @endcode
152/// And then we can create a sample 'Team' and print it to standard output using
153/// our 'toJson' functions,
154/// @code
155/// void example()
156/// {
157/// Employee manager = { 1, "Michael", "Bloomberg" };
158/// Employee employee0 = { 2, "Peter", "Grauer" };
159/// Employee employee1 = { 3, "Tom", "Secunda" };
160///
161/// Team team;
162/// team.d_manager = manager;
163/// team.d_members.push_back(employee0);
164/// team.d_members.push_back(employee1);
165///
166/// bdljsn::Json teamAsJson;
167/// Utility::toJson(&teamAsJson, team);
168///
169/// // The following set of options to 'write' specify that we would prefer
170/// // the output to be pretty-printed.
171/// bdljsn::WriteOptions options;
172/// options.setStyle(bdljsn::WriteStyle::e_PRETTY);
173///
174/// int rc = bdljsn::JsonUtil::write(bsl::cout, teamAsJson, options);
175/// assert(0 == rc);
176/// }
177/// @endcode
178/// Then, we can observe the following printed to standard output:
179/// @code
180/// {
181/// "manager": {
182/// "id": 1,
183/// "firstName": "Michael",
184/// "lastName": "Bloomberg"
185/// },
186/// "members": [
187/// {
188/// "id": 2,
189/// "firstName": "Peter",
190/// "lastName": "Grauer"
191/// },
192/// {
193/// "id": 3,
194/// "firstName": "Tom",
195/// "lastName": "Secunda"
196/// }
197/// ]
198/// }
199/// @endcode
200///
201/// ## Hierarchical Synopsis
202///
203/// The 'bdljsn' package currently has 15 components having 5 levels of physical
204/// dependency. The list below shows the hierarchical ordering of the components.
205/// The order of components within each level is not architecturally significant,
206/// just alphabetical.
207/// @code
208/// 5. bdljsn_jsonliterals
209///
210/// 4. bdljsn_jsonutil
211///
212/// 3. bdljsn_json
213///
214/// 2. bdljsn_error
215/// bdljsn_jsonnumber
216/// bdljsn_tokenizer
217/// bdljsn_writeoptions
218///
219/// 1. bdljsn_jsonnull
220/// bdljsn_jsontestsuiteutil
221/// bdljsn_jsontype
222/// bdljsn_location
223/// bdljsn_numberutil
224/// bdljsn_readoptions
225/// bdljsn_stringutil
226/// bdljsn_writestyle
227/// @endcode
228///
229/// ## Component Synopsis
230///
231/// @ref bdljsn_error :
232/// Provide a description of an error processing a document.
233///
234/// @ref bdljsn_json :
235/// Provide an in-memory representation of a JSON document.
236///
237/// @ref bdljsn_jsonliterals :
238/// Provide user-defined literals for `bdljsn::Json` objects.
239///
240/// @ref bdljsn_jsonnull :
241/// Provide a type that represents the JSON `null` value.
242///
243/// @ref bdljsn_jsonnumber :
244/// Provide a value-semantic type representing a JSON number.
245///
246/// @ref bdljsn_jsontestsuiteutil :
247/// Provide JSON Test Suite for BDE table-driven testing.
248///
249/// @ref bdljsn_jsontype :
250/// Enumerate the set of JSON value types.
251///
252/// @ref bdljsn_jsonutil :
253/// Provide common non-primitive operations on `Json` objects.
254///
255/// @ref bdljsn_location :
256/// Provide a value-semantic type for location in a JSON document.
257///
258/// @ref bdljsn_numberutil :
259/// Provide utilities converting between JSON text and numeric types.
260///
261/// @ref bdljsn_readoptions :
262/// Provide options for reading a JSON document.
263///
264/// @ref bdljsn_stringutil :
265/// Provide a utility functions for JSON strings.
266///
267/// @ref bdljsn_tokenizer :
268/// Provide a tokenizer for extracting JSON data from a `streambuf`.
269///
270/// @ref bdljsn_writeoptions :
271/// Provide options for writing a JSON document.
272///
273/// @ref bdljsn_writestyle :
274/// Enumerate the formatting styles for a writing a JSON document.
275///
276/// @}
277/** @} */