blob: 4b39b7e4a9ba85dbf79e907c627c866ee989d85c [file] [log] [blame]
Shawn McCarney0e8c68a2020-03-27 01:44:48 -05001/**
2 * Copyright © 2020 IBM Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#pragma once
17
18#include "action.hpp"
Bob King3a787542020-04-14 13:45:01 +080019#include "and_action.hpp"
Shawn McCarney0e8c68a2020-03-27 01:44:48 -050020#include "chassis.hpp"
Bob Kingb267b7e2020-04-22 14:42:39 +080021#include "compare_presence_action.hpp"
Bob Kingf2134322020-04-27 14:14:56 +080022#include "compare_vpd_action.hpp"
Bob King9c36c5f2020-04-06 11:34:09 +080023#include "configuration.hpp"
Bob King0e701132020-04-03 21:50:31 +080024#include "device.hpp"
Bob Kingf09bfe02020-04-13 17:21:15 +080025#include "i2c_compare_bit_action.hpp"
26#include "i2c_compare_byte_action.hpp"
27#include "i2c_compare_bytes_action.hpp"
Bob King9c36c5f2020-04-06 11:34:09 +080028#include "i2c_interface.hpp"
Bob Kingf617f892020-03-30 19:03:35 +080029#include "i2c_write_bit_action.hpp"
Bob King87ff9d72020-03-31 14:02:55 +080030#include "i2c_write_byte_action.hpp"
Bob Kingbafcb862020-03-31 16:39:00 +080031#include "i2c_write_bytes_action.hpp"
Bob King93a89d72020-04-15 15:11:11 +080032#include "if_action.hpp"
Bob Kingf1b58dc2020-04-14 14:53:10 +080033#include "not_action.hpp"
Bob King0b51a9b2020-04-15 13:24:18 +080034#include "or_action.hpp"
Bob King84614882020-04-30 13:13:48 +080035#include "pmbus_read_sensor_action.hpp"
Shawn McCarney0e8c68a2020-03-27 01:44:48 -050036#include "pmbus_write_vout_command_action.hpp"
Bob King9c36c5f2020-04-06 11:34:09 +080037#include "presence_detection.hpp"
38#include "rail.hpp"
Shawn McCarney0e8c68a2020-03-27 01:44:48 -050039#include "rule.hpp"
Bob King315b0b62020-04-03 21:47:58 +080040#include "run_rule_action.hpp"
Bob Kinga2f2a0d2020-04-09 13:32:14 +080041#include "sensor_monitoring.hpp"
Bob King18a68502020-04-17 14:19:56 +080042#include "set_device_action.hpp"
Shawn McCarney0e8c68a2020-03-27 01:44:48 -050043
44#include <nlohmann/json.hpp>
45
46#include <cstdint>
47#include <filesystem>
48#include <memory>
49#include <stdexcept>
50#include <string>
51#include <tuple>
52#include <vector>
53
54namespace phosphor::power::regulators::config_file_parser
55{
56
57/**
58 * Parses the specified JSON configuration file.
59 *
60 * Returns the corresponding C++ Rule and Chassis objects.
61 *
62 * Throws a ConfigFileParserError if an error occurs.
63 *
64 * @param pathName configuration file path name
65 * @return tuple containing vectors of Rule and Chassis objects
66 */
67std::tuple<std::vector<std::unique_ptr<Rule>>,
68 std::vector<std::unique_ptr<Chassis>>>
69 parse(const std::filesystem::path& pathName);
70
71/*
72 * Internal implementation details for parse()
73 */
74namespace internal
75{
76
77/**
78 * Returns the specified property of the specified JSON element.
79 *
80 * Throws an invalid_argument exception if the property does not exist.
81 *
82 * @param element JSON element
83 * @param property property name
84 */
85inline const nlohmann::json& getRequiredProperty(const nlohmann::json& element,
86 const std::string& property)
87{
88 auto it = element.find(property);
89 if (it == element.end())
90 {
91 throw std::invalid_argument{"Required property missing: " + property};
92 }
93 return *it;
94}
95
96/**
97 * Parses a JSON element containing an action.
98 *
99 * Returns the corresponding C++ Action object.
100 *
101 * Throws an exception if parsing fails.
102 *
103 * @param element JSON element
104 * @return Action object
105 */
106std::unique_ptr<Action> parseAction(const nlohmann::json& element);
107
108/**
109 * Parses a JSON element containing an array of actions.
110 *
111 * Returns the corresponding C++ Action objects.
112 *
113 * Throws an exception if parsing fails.
114 *
115 * @param element JSON element
116 * @return vector of Action objects
117 */
118std::vector<std::unique_ptr<Action>>
119 parseActionArray(const nlohmann::json& element);
120
121/**
Bob King3a787542020-04-14 13:45:01 +0800122 * Parses a JSON element containing an and action.
123 *
124 * Returns the corresponding C++ AndAction object.
125 *
126 * Throws an exception if parsing fails.
127 *
128 * @param element JSON element
129 * @return AndAction object
130 */
131std::unique_ptr<AndAction> parseAnd(const nlohmann::json& element);
132
133/**
Bob Kingf617f892020-03-30 19:03:35 +0800134 * Parses a JSON element containing a bit position (from 0-7).
135 *
136 * Returns the corresponding C++ uint8_t value.
137 *
138 * Throws an exception if parsing fails.
139 *
140 * @param element JSON element
141 * @return uint8_t value
142 */
143inline uint8_t parseBitPosition(const nlohmann::json& element)
144{
145 // Verify element contains an integer
146 if (!element.is_number_integer())
147 {
148 throw std::invalid_argument{"Element is not an integer"};
149 }
Bob King6afbf1a2020-04-06 17:19:01 +0800150 int value = element.get<int>();
Bob Kingf617f892020-03-30 19:03:35 +0800151 if ((value < 0) || (value > 7))
152 {
153 throw std::invalid_argument{"Element is not a bit position"};
154 }
155 return static_cast<uint8_t>(value);
156}
157
158/**
159 * Parses a JSON element containing a bit value (0 or 1).
160 *
161 * Returns the corresponding C++ uint8_t value.
162 *
163 * Throws an exception if parsing fails.
164 *
165 * @param element JSON element
166 * @return uint8_t value
167 */
168inline uint8_t parseBitValue(const nlohmann::json& element)
169{
170 // Verify element contains an integer
171 if (!element.is_number_integer())
172 {
173 throw std::invalid_argument{"Element is not an integer"};
174 }
Bob King6afbf1a2020-04-06 17:19:01 +0800175 int value = element.get<int>();
Bob Kingf617f892020-03-30 19:03:35 +0800176 if ((value < 0) || (value > 1))
177 {
178 throw std::invalid_argument{"Element is not a bit value"};
179 }
180 return static_cast<uint8_t>(value);
181}
182
183/**
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500184 * Parses a JSON element containing a boolean.
185 *
186 * Returns the corresponding C++ boolean value.
187 *
188 * Throws an exception if parsing fails.
189 *
190 * @param element JSON element
191 * @return boolean value
192 */
193inline bool parseBoolean(const nlohmann::json& element)
194{
195 // Verify element contains a boolean
196 if (!element.is_boolean())
197 {
198 throw std::invalid_argument{"Element is not a boolean"};
199 }
200 return element.get<bool>();
201}
202
203/**
Bob King0e701132020-04-03 21:50:31 +0800204 * Parses a JSON element containing a chassis.
205 *
206 * Returns the corresponding C++ Chassis object.
207 *
208 * Throws an exception if parsing fails.
209 *
210 * @param element JSON element
211 * @return Chassis object
212 */
213std::unique_ptr<Chassis> parseChassis(const nlohmann::json& element);
214
215/**
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500216 * Parses a JSON element containing an array of chassis.
217 *
218 * Returns the corresponding C++ Chassis objects.
219 *
220 * Throws an exception if parsing fails.
221 *
222 * @param element JSON element
223 * @return vector of Chassis objects
224 */
225std::vector<std::unique_ptr<Chassis>>
226 parseChassisArray(const nlohmann::json& element);
227
228/**
Bob Kingb267b7e2020-04-22 14:42:39 +0800229 * Parses a JSON element containing a compare_presence action.
230 *
231 * Returns the corresponding C++ ComparePresenceAction object.
232 *
233 * Throws an exception if parsing fails.
234 *
235 * @param element JSON element
236 * @return ComparePresenceAction object
237 */
238std::unique_ptr<ComparePresenceAction>
239 parseComparePresence(const nlohmann::json& element);
240
241/**
Bob Kingf2134322020-04-27 14:14:56 +0800242 * Parses a JSON element containing a compare_vpd action.
243 *
244 * Returns the corresponding C++ CompareVPDAction object.
245 *
246 * Throws an exception if parsing fails.
247 *
248 * @param element JSON element
249 * @return CompareVPDAction object
250 */
251std::unique_ptr<CompareVPDAction>
252 parseCompareVPD(const nlohmann::json& element);
253
254/**
Bob King33e7eaa2020-04-01 18:09:34 +0800255 * Parses a JSON element containing a configuration.
256 *
257 * Returns the corresponding C++ Configuration object.
258 *
259 * Throws an exception if parsing fails.
260 *
261 * @param element JSON element
262 * @return Configuration object
263 */
264std::unique_ptr<Configuration>
265 parseConfiguration(const nlohmann::json& element);
266
267/**
Bob King9c36c5f2020-04-06 11:34:09 +0800268 * Parses a JSON element containing a device.
269 *
270 * Returns the corresponding C++ Device object.
271 *
272 * Throws an exception if parsing fails.
273 *
274 * @param element JSON element
275 * @return Device object
276 */
277std::unique_ptr<Device> parseDevice(const nlohmann::json& element);
278
279/**
Bob King0e701132020-04-03 21:50:31 +0800280 * Parses a JSON element containing an array of devices.
281 *
282 * Returns the corresponding C++ Device objects.
283 *
284 * Throws an exception if parsing fails.
285 *
286 * @param element JSON element
287 * @return vector of Device objects
288 */
289std::vector<std::unique_ptr<Device>>
290 parseDeviceArray(const nlohmann::json& element);
291
292/**
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500293 * Parses a JSON element containing a double (floating point number).
294 *
295 * Returns the corresponding C++ double value.
296 *
297 * Throws an exception if parsing fails.
298 *
299 * @param element JSON element
300 * @return double value
301 */
302inline double parseDouble(const nlohmann::json& element)
303{
304 // Verify element contains a number (integer or floating point)
305 if (!element.is_number())
306 {
307 throw std::invalid_argument{"Element is not a number"};
308 }
309 return element.get<double>();
310}
311
312/**
Bob Kingbafcb862020-03-31 16:39:00 +0800313 * Parses a JSON element containing a byte value expressed as a hexadecimal
314 * string.
315 *
316 * The JSON number data type does not support the hexadecimal format. For this
317 * reason, hexadecimal byte values are stored as strings in the configuration
318 * file.
319 *
320 * Returns the corresponding C++ uint8_t value.
321 *
322 * Throws an exception if parsing fails.
323 *
324 * @param element JSON element
325 * @return uint8_t value
326 */
327inline uint8_t parseHexByte(const nlohmann::json& element)
328{
329 if (!element.is_string())
330 {
331 throw std::invalid_argument{"Element is not a string"};
332 }
Bob King6afbf1a2020-04-06 17:19:01 +0800333 std::string value = element.get<std::string>();
Bob Kingbafcb862020-03-31 16:39:00 +0800334
335 bool isHex = (value.compare(0, 2, "0x") == 0) && (value.size() > 2) &&
336 (value.size() < 5) &&
337 (value.find_first_not_of("0123456789abcdefABCDEF", 2) ==
338 std::string::npos);
339 if (!isHex)
340 {
341 throw std::invalid_argument{"Element is not hexadecimal string"};
342 }
343 return static_cast<uint8_t>(std::stoul(value, 0, 0));
344}
345
346/**
347 * Parses a JSON element containing an array of byte values expressed as a
348 * hexadecimal strings.
349 *
350 * Returns the corresponding C++ uint8_t values.
351 *
352 * Throws an exception if parsing fails.
353 *
354 * @param element JSON element
355 * @return vector of uint8_t
356 */
357std::vector<uint8_t> parseHexByteArray(const nlohmann::json& element);
358
359/**
Bob Kingf09bfe02020-04-13 17:21:15 +0800360 * Parses a JSON element containing an i2c_compare_bit action.
361 *
362 * Returns the corresponding C++ I2CCompareBitAction object.
363 *
364 * Throws an exception if parsing fails.
365 *
366 * @param element JSON element
367 * @return I2CCompareBitAction object
368 */
369std::unique_ptr<I2CCompareBitAction>
370 parseI2CCompareBit(const nlohmann::json& element);
371
372/**
373 * Parses a JSON element containing an i2c_compare_byte action.
374 *
375 * Returns the corresponding C++ I2CCompareByteAction object.
376 *
377 * Throws an exception if parsing fails.
378 *
379 * @param element JSON element
380 * @return I2CCompareByteAction object
381 */
382std::unique_ptr<I2CCompareByteAction>
383 parseI2CCompareByte(const nlohmann::json& element);
384
385/**
386 * Parses a JSON element containing an i2c_compare_bytes action.
387 *
388 * Returns the corresponding C++ I2CCompareBytesAction object.
389 *
390 * Throws an exception if parsing fails.
391 *
392 * @param element JSON element
393 * @return I2CCompareBytesAction object
394 */
395std::unique_ptr<I2CCompareBytesAction>
396 parseI2CCompareBytes(const nlohmann::json& element);
397
398/**
Bob King9c36c5f2020-04-06 11:34:09 +0800399 * Parses a JSON element containing an i2c_interface.
400 *
401 * Returns the corresponding C++ i2c::I2CInterface object.
402 *
403 * Throws an exception if parsing fails.
404 *
405 * @param element JSON element
406 * @return i2c::I2CInterface object
407 */
408std::unique_ptr<i2c::I2CInterface>
409 parseI2CInterface(const nlohmann::json& element);
410
411/**
Bob Kingf617f892020-03-30 19:03:35 +0800412 * Parses a JSON element containing an i2c_write_bit action.
413 *
414 * Returns the corresponding C++ I2CWriteBitAction object.
415 *
416 * Throws an exception if parsing fails.
417 *
418 * @param element JSON element
419 * @return I2CWriteBitAction object
420 */
421std::unique_ptr<I2CWriteBitAction>
422 parseI2CWriteBit(const nlohmann::json& element);
423
424/**
Bob King87ff9d72020-03-31 14:02:55 +0800425 * Parses a JSON element containing an i2c_write_byte action.
426 *
427 * Returns the corresponding C++ I2CWriteByteAction object.
428 *
429 * Throws an exception if parsing fails.
430 *
431 * @param element JSON element
432 * @return I2CWriteByteAction object
433 */
434std::unique_ptr<I2CWriteByteAction>
435 parseI2CWriteByte(const nlohmann::json& element);
436
437/**
Bob Kingbafcb862020-03-31 16:39:00 +0800438 * Parses a JSON element containing an i2c_write_bytes action.
439 *
440 * Returns the corresponding C++ I2CWriteBytesAction object.
441 *
442 * Throws an exception if parsing fails.
443 *
444 * @param element JSON element
445 * @return I2CWriteBytesAction object
446 */
447std::unique_ptr<I2CWriteBytesAction>
448 parseI2CWriteBytes(const nlohmann::json& element);
449
450/**
Bob King93a89d72020-04-15 15:11:11 +0800451 * Parses a JSON element containing an if action.
452 *
453 * Returns the corresponding C++ IfAction object.
454 *
455 * Throws an exception if parsing fails.
456 *
457 * @param element JSON element
458 * @return IfAction object
459 */
460std::unique_ptr<IfAction> parseIf(const nlohmann::json& element);
461
462/**
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500463 * Parses a JSON element containing an 8-bit signed integer.
464 *
465 * Returns the corresponding C++ int8_t value.
466 *
467 * Throws an exception if parsing fails.
468 *
469 * @param element JSON element
470 * @return int8_t value
471 */
472inline int8_t parseInt8(const nlohmann::json& element)
473{
474 // Verify element contains an integer
475 if (!element.is_number_integer())
476 {
477 throw std::invalid_argument{"Element is not an integer"};
478 }
Bob King6afbf1a2020-04-06 17:19:01 +0800479 int value = element.get<int>();
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500480 if ((value < INT8_MIN) || (value > INT8_MAX))
481 {
482 throw std::invalid_argument{"Element is not an 8-bit signed integer"};
483 }
484 return static_cast<int8_t>(value);
485}
486
487/**
Bob Kinga76898f2020-10-13 15:08:33 +0800488 * Parses a JSON element containing a relative inventory path.
489 *
490 * Returns the corresponding C++ string containing the absolute inventory path.
491 *
492 * Inventory paths in the JSON configuration file are relative. Adds the
493 * necessary prefix to make the path absolute.
494 *
495 * Throws an exception if parsing fails.
496 *
497 * @param element JSON element
498 * @return absolute D-Bus inventory path
499 */
500std::string parseInventoryPath(const nlohmann::json& element);
501
502/**
Bob Kingf1b58dc2020-04-14 14:53:10 +0800503 * Parses a JSON element containing a not action.
504 *
505 * Returns the corresponding C++ NotAction object.
506 *
507 * Throws an exception if parsing fails.
508 *
509 * @param element JSON element
510 * @return NotAction object
511 */
512std::unique_ptr<NotAction> parseNot(const nlohmann::json& element);
513
514/**
Bob King0b51a9b2020-04-15 13:24:18 +0800515 * Parses a JSON element containing an or action.
516 *
517 * Returns the corresponding C++ OrAction object.
518 *
519 * Throws an exception if parsing fails.
520 *
521 * @param element JSON element
522 * @return OrAction object
523 */
524std::unique_ptr<OrAction> parseOr(const nlohmann::json& element);
525
526/**
Bob King84614882020-04-30 13:13:48 +0800527 * Parses a JSON element containing a pmbus_read_sensor action.
528 *
529 * Returns the corresponding C++ PMBusReadSensorAction object.
530 *
531 * Throws an exception if parsing fails.
532 *
533 * @param element JSON element
534 * @return PMBusReadSensorAction object
535 */
536std::unique_ptr<PMBusReadSensorAction>
537 parsePMBusReadSensor(const nlohmann::json& element);
538
539/**
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500540 * Parses a JSON element containing a pmbus_write_vout_command action.
541 *
542 * Returns the corresponding C++ PMBusWriteVoutCommandAction object.
543 *
544 * Throws an exception if parsing fails.
545 *
546 * @param element JSON element
547 * @return PMBusWriteVoutCommandAction object
548 */
549std::unique_ptr<PMBusWriteVoutCommandAction>
550 parsePMBusWriteVoutCommand(const nlohmann::json& element);
551
552/**
Bob King2aafb1c2020-04-16 15:24:32 +0800553 * Parses a JSON element containing a presence detection operation.
554 *
555 * Returns the corresponding C++ PresenceDetection object.
556 *
557 * Throws an exception if parsing fails.
558 *
559 * @param element JSON element
560 * @return PresenceDetection object
561 */
562std::unique_ptr<PresenceDetection>
563 parsePresenceDetection(const nlohmann::json& element);
564
565/**
Bob Kinga2f2a0d2020-04-09 13:32:14 +0800566 * Parses a JSON element containing a rail.
567 *
568 * Returns the corresponding C++ Rail object.
569 *
570 * Throws an exception if parsing fails.
571 *
572 * @param element JSON element
573 * @return Rail object
574 */
575std::unique_ptr<Rail> parseRail(const nlohmann::json& element);
576
577/**
Bob King9c36c5f2020-04-06 11:34:09 +0800578 * Parses a JSON element containing an array of rails.
579 *
580 * Returns the corresponding C++ Rail objects.
581 *
582 * Throws an exception if parsing fails.
583 *
584 * @param element JSON element
585 * @return vector of Rail objects
586 */
587std::vector<std::unique_ptr<Rail>>
588 parseRailArray(const nlohmann::json& element);
589
590/**
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500591 * Parses the JSON root element of the entire configuration file.
592 *
593 * Returns the corresponding C++ Rule and Chassis objects.
594 *
595 * Throws an exception if parsing fails.
596 *
597 * @param element JSON element
598 * @return tuple containing vectors of Rule and Chassis objects
599 */
600std::tuple<std::vector<std::unique_ptr<Rule>>,
601 std::vector<std::unique_ptr<Chassis>>>
602 parseRoot(const nlohmann::json& element);
603
604/**
605 * Parses a JSON element containing a rule.
606 *
607 * Returns the corresponding C++ Rule object.
608 *
609 * Throws an exception if parsing fails.
610 *
611 * @param element JSON element
612 * @return Rule object
613 */
614std::unique_ptr<Rule> parseRule(const nlohmann::json& element);
615
616/**
617 * Parses a JSON element containing an array of rules.
618 *
619 * Returns the corresponding C++ Rule objects.
620 *
621 * Throws an exception if parsing fails.
622 *
623 * @param element JSON element
624 * @return vector of Rule objects
625 */
626std::vector<std::unique_ptr<Rule>>
627 parseRuleArray(const nlohmann::json& element);
628
629/**
Bob King33e7eaa2020-04-01 18:09:34 +0800630 * Parses the "rule_id" or "actions" property in a JSON element.
631 *
632 * The element must contain one property or the other but not both.
633 *
634 * If the element contains a "rule_id" property, the corresponding C++
635 * RunRuleAction object is returned.
636 *
637 * If the element contains an "actions" property, the corresponding C++ Action
638 * objects are returned.
639 *
640 * Throws an exception if parsing fails.
641 *
642 * @param element JSON element
643 * @return vector of Action objects
644 */
645std::vector<std::unique_ptr<Action>>
646 parseRuleIDOrActionsProperty(const nlohmann::json& element);
647
648/**
Bob King315b0b62020-04-03 21:47:58 +0800649 * Parses a JSON element containing a run_rule action.
650 *
651 * Returns the corresponding C++ RunRuleAction object.
652 *
653 * Throws an exception if parsing fails.
654 *
655 * @param element JSON element
656 * @return RunRuleAction object
657 */
658std::unique_ptr<RunRuleAction> parseRunRule(const nlohmann::json& element);
659
660/**
Bob King84614882020-04-30 13:13:48 +0800661 * Parses a JSON element containing a SensorDataFormat expressed as a string.
662 *
663 * Returns the corresponding SensorDataFormat enum value.
664 *
665 * Throws an exception if parsing fails.
666 *
667 * @param element JSON element
668 * @return SensorDataFormat enum value
669 */
670pmbus_utils::SensorDataFormat
671 parseSensorDataFormat(const nlohmann::json& element);
672
673/**
Bob Kinga2f2a0d2020-04-09 13:32:14 +0800674 * Parses a JSON element containing a sensor monitoring operation.
675 *
676 * Returns the corresponding C++ SensorMonitoring object.
677 *
678 * Throws an exception if parsing fails.
679 *
680 * @param element JSON element
681 * @return SensorMonitoring object
682 */
683std::unique_ptr<SensorMonitoring>
684 parseSensorMonitoring(const nlohmann::json& element);
685
686/**
Bob King84614882020-04-30 13:13:48 +0800687 * Parses a JSON element containing a SensorValueType expressed as a string.
688 *
689 * Returns the corresponding SensorValueType enum value.
690 *
691 * Throws an exception if parsing fails.
692 *
693 * @param element JSON element
694 * @return SensorValueType enum value
695 */
696pmbus_utils::SensorValueType
697 parseSensorValueType(const nlohmann::json& element);
698
699/**
Bob King18a68502020-04-17 14:19:56 +0800700 * Parses a JSON element containing a set_device action.
701 *
702 * Returns the corresponding C++ SetDeviceAction object.
703 *
704 * Throws an exception if parsing fails.
705 *
706 * @param element JSON element
707 * @return SetDeviceAction object
708 */
709std::unique_ptr<SetDeviceAction> parseSetDevice(const nlohmann::json& element);
710
711/**
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500712 * Parses a JSON element containing a string.
713 *
714 * Returns the corresponding C++ string.
715 *
716 * Throws an exception if parsing fails.
717 *
718 * @param element JSON element
719 * @param isEmptyValid indicates whether an empty string value is valid
720 * @return string value
721 */
722inline std::string parseString(const nlohmann::json& element,
723 bool isEmptyValid = false)
724{
725 if (!element.is_string())
726 {
727 throw std::invalid_argument{"Element is not a string"};
728 }
Bob King6afbf1a2020-04-06 17:19:01 +0800729 std::string value = element.get<std::string>();
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500730 if (value.empty() && !isEmptyValid)
731 {
732 throw std::invalid_argument{"Element contains an empty string"};
733 }
734 return value;
735}
736
737/**
Bob Kingf617f892020-03-30 19:03:35 +0800738 * Parses a JSON element containing an 8-bit unsigned integer.
739 *
740 * Returns the corresponding C++ uint8_t value.
741 *
742 * Throws an exception if parsing fails.
743 *
744 * @param element JSON element
745 * @return uint8_t value
746 */
747inline uint8_t parseUint8(const nlohmann::json& element)
748{
749 // Verify element contains an integer
750 if (!element.is_number_integer())
751 {
752 throw std::invalid_argument{"Element is not an integer"};
753 }
Bob King6afbf1a2020-04-06 17:19:01 +0800754 int value = element.get<int>();
Bob Kingf617f892020-03-30 19:03:35 +0800755 if ((value < 0) || (value > UINT8_MAX))
756 {
757 throw std::invalid_argument{"Element is not an 8-bit unsigned integer"};
758 }
759 return static_cast<uint8_t>(value);
760}
761
762/**
Bob King0e701132020-04-03 21:50:31 +0800763 * Parses a JSON element containing an unsigned integer.
764 *
765 * Returns the corresponding C++ unsigned int value.
766 *
767 * Throws an exception if parsing fails.
768 *
769 * @param element JSON element
770 * @return unsigned int value
771 */
772inline unsigned int parseUnsignedInteger(const nlohmann::json& element)
773{
774 // Verify element contains an unsigned integer
775 if (!element.is_number_unsigned())
776 {
777 throw std::invalid_argument{"Element is not an unsigned integer"};
778 }
779 return element.get<unsigned int>();
780}
781
782/**
Bob King84614882020-04-30 13:13:48 +0800783 * Parses a JSON element containing a VoutDataFormat expressed as a string.
784 *
785 * Returns the corresponding VoutDataFormat enum value.
786 *
787 * Throws an exception if parsing fails.
788 *
789 * @param element JSON element
790 * @return VoutDataFormat enum value
791 */
792pmbus_utils::VoutDataFormat parseVoutDataFormat(const nlohmann::json& element);
793
794/**
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500795 * Verifies that the specified JSON element is a JSON array.
796 *
797 * Throws an invalid_argument exception if the element is not an array.
798 *
799 * @param element JSON element
800 */
801inline void verifyIsArray(const nlohmann::json& element)
802{
803 if (!element.is_array())
804 {
805 throw std::invalid_argument{"Element is not an array"};
806 }
807}
808
809/**
810 * Verifies that the specified JSON element is a JSON object.
811 *
812 * Throws an invalid_argument exception if the element is not an object.
813 *
814 * @param element JSON element
815 */
816inline void verifyIsObject(const nlohmann::json& element)
817{
818 if (!element.is_object())
819 {
820 throw std::invalid_argument{"Element is not an object"};
821 }
822}
823
824/**
825 * Verifies that the specified JSON element contains the expected number of
826 * properties.
827 *
828 * Throws an invalid_argument exception if the element contains a different
829 * number of properties. This indicates the element contains an invalid
830 * property.
831 *
832 * @param element JSON element
833 * @param expectedCount expected number of properties in element
834 */
835inline void verifyPropertyCount(const nlohmann::json& element,
836 unsigned int expectedCount)
837{
838 if (element.size() != expectedCount)
839 {
840 throw std::invalid_argument{"Element contains an invalid property"};
841 }
842}
843
844} // namespace internal
845
846} // namespace phosphor::power::regulators::config_file_parser