RStudio Launcher Plugin SDK  1.1.3
A software development kit for creating plugins that work the the RStudio Launcher.
Json.hpp
Go to the documentation of this file.
1 /*
2  * Json.hpp
3  *
4  * Copyright (C) 2022 by RStudio, PBC
5  *
6  * Unless you have received this program directly from RStudio pursuant to the terms of a commercial license agreement
7  * with RStudio, then this program is licensed to you under the following terms:
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
10  * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
11  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
12  * permit persons to whom the Software is furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
15  * Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
18  * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  *
22  */
23 
24 #ifndef LAUNCHER_PLUGINS_JSON_HPP
25 #define LAUNCHER_PLUGINS_JSON_HPP
26 
27 #include <map>
28 #include <ostream>
29 #include <set>
30 #include <sstream>
31 #include <utility>
32 #include <vector>
33 
34 #include <Optional.hpp>
35 
36 #include <Error.hpp>
37 #include <logging/Logger.hpp>
38 #include <PImpl.hpp>
39 
40 namespace rstudio {
41 namespace launcher_plugins {
42 namespace json {
43 
50 class Array;
51 class Object;
52 
53 typedef std::vector<std::pair<std::string, std::string> > StringPairList;
54 typedef std::map<std::string, std::vector<std::string> > StringListMap;
55 
59 enum class Type
60 {
61  ARRAY,
62  BOOL,
63  INTEGER,
64  OBJECT,
65  STRING,
66  REAL,
67  NULL_TYPE,
68  UNKNOWN
69 };
70 
74 class Value
75 {
76 protected:
77  // This is defined first so it may be referred to in the class definition.
81  PRIVATE_IMPL_SHARED(m_impl);
82 
86  typedef std::shared_ptr<Impl> ValueImplPtr;
87 
88  friend class Array;
89 
90 public:
94  Value();
95 
101  explicit Value(ValueImplPtr in_valueImpl);
102 
108  Value(const Value& in_other);
109 
115  Value(Value&& in_other) noexcept;
116 
122  explicit Value(bool in_value);
123 
129  explicit Value(double in_value);
130 
136  explicit Value(float in_value);
137 
143  explicit Value(int in_value);
144 
150  explicit Value(int64_t in_value);
151 
157  explicit Value(const char* in_value);
158 
164  explicit Value(const std::string& in_value);
165 
171  explicit Value(unsigned int in_value);
172 
178  explicit Value(uint64_t in_value);
179 
183  virtual ~Value() = default;
184 
192  Value& operator=(const Value& in_other);
193 
201  Value& operator=(Value&& in_other) noexcept;
202 
210  Value& operator=(bool in_value);
211 
219  Value& operator=(double in_value);
220 
228  Value& operator=(float in_value);
229 
237  Value& operator=(int in_value);
238 
246  Value& operator=(int64_t in_value);
247 
255  Value& operator=(const char* in_value);
256 
264  Value& operator=(const std::string& in_value);
265 
273  Value& operator=(unsigned int in_value);
274 
282  Value& operator=(uint64_t in_value);
283 
291  bool operator==(const Value& in_other) const;
292 
300  bool operator!=(const Value& in_other) const;
301 
307  Value clone() const;
308 
318  Error coerce(const std::string& in_schema,
319  std::vector<std::string>& out_propViolations);
320 
327  Array getArray() const;
328 
334  bool getBool() const;
335 
341  double getDouble() const;
342 
348  float getFloat() const;
349 
355  int getInt() const;
356 
362  int64_t getInt64() const;
363 
370  Object getObject() const;
371 
377  std::string getString() const;
378 
384  Type getType() const;
385 
392  unsigned int getUInt() const;
393 
399  uint64_t getUInt64() const;
400 
410  template <typename T>
411  T getValue() const;
412 
418  bool isArray() const;
419 
425  bool isBool() const;
426 
432  bool isDouble() const;
433 
439  bool isFloat() const;
440 
446  bool isInt() const;
447 
453  bool isInt64() const;
454 
460  bool isObject() const;
461 
467  bool isString() const;
468 
474  bool isNull() const;
475 
481  bool isUInt() const;
482 
488  bool isUInt64() const;
489 
497  virtual Error parse(const char* in_jsonStr);
498 
506  virtual Error parse(const std::string& in_jsonStr);
507 
516  Error parseAndValidate(const std::string& in_jsonStr, const std::string& in_schema);
517 
526  Error setValueAtPointerPath(const std::string& in_pointerPath, const json::Value& in_value);
527 
536  Error setValueAtPointerPath(const std::string& in_pointerPath, bool in_value);
537 
546  Error setValueAtPointerPath(const std::string& in_pointerPath, double in_value);
547 
556  Error setValueAtPointerPath(const std::string& in_pointerPath, float in_value);
557 
566  Error setValueAtPointerPath(const std::string& in_pointerPath, int in_value);
567 
576  Error setValueAtPointerPath(const std::string& in_pointerPath, int64_t in_value);
577 
586  Error setValueAtPointerPath(const std::string& in_pointerPath, const char* in_value);
587 
596  Error setValueAtPointerPath(const std::string& in_pointerPath, const std::string& in_value);
597 
606  Error setValueAtPointerPath(const std::string& in_pointerPath, unsigned int in_value);
607 
616  Error setValueAtPointerPath(const std::string& in_pointerPath, uint64_t in_value);
617 
626  Error setValueAtPointerPath(const std::string& in_pointerPath, const Array& in_value);
627 
636  Error setValueAtPointerPath(const std::string& in_pointerPath, const Object& in_value);
637 
645  Error validate(const std::string& in_schema) const;
646 
652  std::string write() const;
653 
659  void write(std::ostream& io_ostream) const;
660 
666  std::string writeFormatted() const;
667 
673  void writeFormatted(std::ostream& io_ostream) const;
674 
675 private:
681  void move(Value&& in_other);
682 };
683 
687 class Object : public Value
688 {
689 public:
690  class Iterator;
691 
695  class Member
696  {
697  private:
698  // Private implementation of member, declared first so it can be used.
699  PRIVATE_IMPL_SHARED(m_impl);
700 
701  // Iterators can construct members.
702  friend class Iterator;
703  public:
707  Member() = default;
708 
714  explicit Member(const std::shared_ptr<Impl>& in_impl);
715 
721  const std::string& getName() const;
722 
728  Value getValue() const;
729  };
730 
734  class Iterator: public std::iterator<
735  std::bidirectional_iterator_tag, // iterator_category
736  Member, // value_type
737  std::ptrdiff_t, // difference_type
738  const Member*, // pointer
739  Member> // reference
740  {
741  public:
748  explicit Iterator(const Object* in_parent, std::ptrdiff_t in_startPos = 0);
749 
755  Iterator(const Iterator& in_other) = default;
756 
764  Iterator& operator=(const Iterator& in_other);
765 
771  Iterator& operator++();
772 
778  Iterator& operator--();
779 
785  Iterator operator++(int);
786 
792  Iterator operator--(int);
793 
799  bool operator==(const Iterator& in_other) const;
800 
806  bool operator!=(const Iterator& in_other) const;
807 
813  reference operator*() const;
814 
815  private:
819  const Object* m_parent;
820 
824  std::ptrdiff_t m_pos;
825 
826  // Let the parent class manipulate its iterators.
827  friend class Object;
828  };
829 
833  typedef std::reverse_iterator<Iterator> ReverseIterator;
834 
838  Object();
839 
845  explicit Object(const StringPairList& in_strPairs);
846 
852  Object(const Object& in_other);
853 
859  Object(Object&& in_other) noexcept;
860 
869  static Member createMember(const std::string& in_name, const Value& in_value);
870 
879  static Error getSchemaDefaults(const std::string& in_schema, Object& out_schemaDefaults);
880 
890  static Object mergeObjects(const Object& in_base, const Object& in_overlay);
891 
899  Object& operator=(const Object& in_other);
900 
908  Object& operator=(Object&& in_other) noexcept;
909 
918  Value operator[](const char* in_name);
919 
928  Value operator[](const std::string& in_name);
929 
937  Iterator find(const char* in_name) const;
938 
946  Iterator find(const std::string& in_name) const;
947 
953  Iterator begin() const;
954 
960  Iterator end() const;
961 
967  ReverseIterator rbegin() const;
968 
975  ReverseIterator rend() const;
976 
980  void clear();
981 
989  bool erase(const char* in_name);
990 
998  bool erase(const std::string& in_name);
999 
1007  Iterator erase(const Iterator& in_itr);
1008 
1014  size_t getSize() const;
1015 
1023  bool hasMember(const char* in_name) const;
1024 
1032  bool hasMember(const std::string& in_name) const;
1033 
1041  void insert(const std::string& in_name, const Value& in_value);
1042 
1050  void insert(const std::string& in_name, bool in_value);
1051 
1059  void insert(const std::string& in_name, double in_value);
1060 
1068  void insert(const std::string& in_name, float in_value);
1069 
1077  void insert(const std::string& in_name, int in_value);
1078 
1086  void insert(const std::string& in_name, int64_t in_value);
1087 
1095  void insert(const std::string& in_name, const char* in_value);
1096 
1104  void insert(const std::string& in_name, const std::string& in_value);
1105 
1113  void insert(const std::string& in_name, unsigned int in_value);
1114 
1122  void insert(const std::string& in_name, uint64_t in_value);
1123 
1131  void insert(const std::string& in_name, const Array& in_value);
1132 
1140  void insert(const std::string& in_name, const Object& in_value);
1141 
1148  void insert(const Member& in_member);
1149 
1155  bool isEmpty() const;
1156 
1165  Error parse(const char* in_jsonStr) override;
1166 
1175  Error parse(const std::string& in_jsonStr) override;
1176 
1184  bool toStringMap(StringListMap& out_map) const;
1185 
1193  StringPairList toStringPairList() const;
1194 
1195 private:
1201  explicit Object(ValueImplPtr in_value);
1202 
1203  friend class Value;
1204  friend class Iterator;
1205 };
1206 
1210 class Array : public Value
1211 {
1212 public:
1213 
1218 
1222  class Iterator: public std::iterator<std::bidirectional_iterator_tag, // iterator_category
1223  Value, // value_type
1224  std::ptrdiff_t, // difference_type
1225  const Value*, // pointer
1226  Value> // reference
1227  {
1228  public:
1235  explicit Iterator(const Array* in_parent, std::ptrdiff_t in_startPos = 0);
1236 
1242  Iterator(const Iterator& in_other) = default;
1243 
1251  Iterator& operator=(const Iterator& in_other);
1252 
1258  Iterator& operator++();
1259 
1265  Iterator& operator--();
1266 
1272  Iterator operator++(int);
1273 
1279  Iterator operator--(int);
1280 
1286  bool operator==(const Iterator& in_other) const;
1287 
1293  bool operator!=(const Iterator& in_other) const;
1294 
1300  reference operator*() const;
1301 
1302  private:
1306  const Array* m_parent;
1307 
1311  std::ptrdiff_t m_pos;
1312 
1313  // Allow the array class to manipulate its own iterators.
1314  friend class Array;
1315  };
1316 
1320  typedef std::reverse_iterator<Iterator> ReverseIterator;
1321 
1325  Array();
1326 
1332  explicit Array(const StringPairList& in_strPairs);
1333 
1339  Array(const Array& in_other);
1340 
1346  Array(Array&& in_other) noexcept;
1347 
1355  Array& operator=(const Array& in_other);
1356 
1364  Array& operator=(Array&& in_other) noexcept;
1365 
1375  Value operator[](size_t in_index) const;
1376 
1382  Iterator begin() const;
1383 
1389  Iterator end() const;
1390 
1396  ReverseIterator rbegin() const;
1397 
1404  ReverseIterator rend() const;
1405 
1409  void clear();
1410 
1418  Iterator erase(const Iterator& in_itr);
1419 
1428  Iterator erase(const Iterator& in_first, const Iterator& in_last);
1429 
1435  Value getBack() const;
1436 
1442  Value getFront() const;
1443 
1451  Value getValueAt(size_t in_index) const;
1452 
1458  size_t getSize() const;
1459 
1465  bool isEmpty() const;
1466 
1475  Error parse(const char* in_jsonStr) override;
1476 
1485  Error parse(const std::string& in_jsonStr) override;
1486 
1495  void push_back(const Value& in_value);
1496 
1505  void push_back(bool in_value);
1506 
1515  void push_back(double in_value);
1516 
1525  void push_back(float in_value);
1526 
1535  void push_back(int in_value);
1536 
1545  void push_back(int64_t in_value);
1546 
1555  void push_back(const char* in_value);
1556 
1565  void push_back(const std::string& in_value);
1566 
1575  void push_back(unsigned int in_value);
1576 
1585  void push_back(uint64_t in_value);
1586 
1595  void push_back(const Array& in_value);
1596 
1605  void push_back(const Object& in_value);
1606 
1614  bool toSetString(std::set<std::string>& out_set) const;
1615 
1623  StringPairList toStringPairList() const;
1624 
1632  bool toVectorInt(std::vector<int>& out_set) const;
1633 
1641  bool toVectorString(std::vector<std::string>& out_set) const;
1642 
1643 private:
1649  explicit Array(ValueImplPtr in_value);
1650 
1651  friend class Value;
1652 };
1653 
1663 template <typename T>
1664 bool isType(const Value& in_value)
1665 {
1666  if (in_value.isNull())
1667  return false;
1668  else if (std::is_same<T, Object>::value)
1669  return in_value.getType() == Type::OBJECT;
1670  else if (std::is_same<T, Array>::value)
1671  return in_value.getType() == Type::ARRAY;
1672  else if (std::is_same<T, std::string>::value)
1673  return in_value.getType() == Type::STRING;
1674  else if (std::is_same<T, bool>::value)
1675  return in_value.getType() == Type::BOOL;
1676  else if (std::is_same<T, int>::value)
1677  return in_value.getType() == Type::INTEGER;
1678  else if (std::is_same<T, unsigned int>::value)
1679  return in_value.getType() == Type::INTEGER;
1680  else if (std::is_same<T, int64_t>::value)
1681  return in_value.getType() == Type::INTEGER;
1682  else if (std::is_same<T, uint64_t>::value)
1683  return in_value.getType() == Type::INTEGER;
1684  else if (std::is_same<T, unsigned long>::value)
1685  return in_value.getType() == Type::INTEGER;
1686  else if (std::is_same<T, double>::value)
1687  return (in_value.getType() == Type::INTEGER) || (in_value.getType() == Type::REAL);
1688  else
1689  return false;
1690 }
1691 
1692 std::string typeAsString(Type in_type);
1693 std::ostream& operator<<(std::ostream& io_ostream, Type in_type);
1694 
1695 namespace detail {
1696 
1703 template <typename T>
1704 struct is_json_type : public std::is_base_of<Value, T>
1705 {
1706 };
1707 
1717 template <typename T>
1718 Type asJsonType(const T& in_object,
1719  std::true_type)
1720 {
1721  return in_object.getType();
1722 }
1723 
1733 template <typename T>
1734 Type asJsonType(const T& in_object,
1735  std::false_type)
1736 {
1737  if (std::is_same<T, bool>::value)
1738  return Type::BOOL;
1739  else if (std::is_same<T, int>::value)
1740  return Type::INTEGER;
1741  else if (std::is_same<T, double>::value)
1742  return Type::REAL;
1743  else if (std::is_same<T, std::string>::value)
1744  return Type::STRING;
1745 
1746  logging::logErrorMessage("Unexpected type");
1747  return Type::NULL_TYPE;
1748 }
1749 
1759 template <typename T>
1760 inline Value toJsonValue(const T& in_value)
1761 {
1762  return Value(in_value);
1763 }
1764 
1774 template <typename T>
1775 inline Value toJsonValue(const Optional<T>& in_value)
1776 {
1777  return in_value ? Value(*in_value) : Value();
1778 }
1779 
1789 template <typename T>
1790 inline Value toJsonValue(const std::vector<T>& in_vector)
1791 {
1792  Array results;
1793  for (auto&& val : in_vector)
1794  {
1795  results.push_back(val);
1796  }
1797 
1798  return std::move(results);
1799 }
1800 
1810 template <typename T>
1811 inline Value toJsonValue(const std::set<T>& in_set)
1812 {
1813  Array results;
1814  for (const T& val : in_set)
1815  {
1816  results.push_back(val);
1817  }
1818 
1819  return std::move(results);
1820 }
1821 
1822 } // namespace detail
1823 
1833 template <typename T>
1834 Type asJsonType(const T& in_object)
1835 {
1836  return detail::asJsonType(
1837  in_object,
1839 }
1840 
1848 inline std::string typeAsString(const Value& in_value)
1849 {
1850  return typeAsString(in_value.getType());
1851 }
1852 
1862 template <typename T>
1863 inline Value toJsonValue(const T& in_value)
1864 {
1865  return detail::toJsonValue(in_value);
1866 }
1867 
1877 template<typename T>
1878 Array toJsonArray(const std::vector<T>& in_vector)
1879 {
1880  return detail::toJsonValue(in_vector).getArray();
1881 }
1882 
1892 template<typename T>
1893 Array toJsonArray(const std::set<T>& in_set)
1894 {
1895  return detail::toJsonValue(in_set).getArray();
1896 }
1897 
1902 enum class JsonReadError
1903 {
1904  SUCCESS = 0,
1905  MISSING_MEMBER = 1,
1906  INVALID_TYPE = 2,
1907 };
1908 
1918 Error jsonReadError(JsonReadError in_errorCode, const std::string& in_message, const ErrorLocation& in_errorLocation);
1919 
1927 bool isMissingMemberError(const Error& in_error);
1928 
1940 template <typename T>
1941 Error readObject(const Object& in_object, const std::string& in_name, T& out_value)
1942 {
1943  Object::Iterator itr = in_object.find(in_name);
1944  if ((itr == in_object.end()) || (*itr).getValue().isNull())
1945  return jsonReadError(
1946  JsonReadError::MISSING_MEMBER,
1947  "Member " + in_name + " does not exist in the specified JSON object.",
1948  ERROR_LOCATION);
1949 
1950  if (!isType<T>((*itr).getValue()))
1951  {
1952  std::ostringstream msgStream;
1953  msgStream << "Member " << in_name << " has type " << (*itr).getValue().getType() <<
1954  " which is not compatible with requested type " << typeid(T).name() << ".";
1955  return jsonReadError(
1956  JsonReadError::INVALID_TYPE,
1957  msgStream.str(),
1958  ERROR_LOCATION);
1959  }
1960 
1961  out_value = (*itr).getValue().getValue<T>();
1962  return Success();
1963 }
1964 
1976 template <typename T>
1977 Error readObject(const Object& in_object, const std::string& in_name, Optional<T>& out_value)
1978 {
1979  // If the value is optional, no need to report that it's missing.
1980  Object::Iterator itr = in_object.find(in_name);
1981  if (itr == in_object.end() || (*itr).getValue().isNull())
1982  return Success();
1983 
1984  if (!isType<T>((*itr).getValue()))
1985  {
1986  std::ostringstream msgStream;
1987  msgStream << "Member " << in_name << " has type " << (*itr).getValue().getType() <<
1988  " which is not compatible with requested type " << typeid(T).name() << ".";
1989  return jsonReadError(
1990  JsonReadError::INVALID_TYPE,
1991  msgStream.str(),
1992  ERROR_LOCATION);
1993  }
1994 
1995  out_value = (*itr).getValue().getValue<T>();
1996  return Success();
1997 }
1998 
2010 template <typename T>
2011 Error readObject(const Object& in_object, const std::string& in_name, std::vector<T>& out_values)
2012 {
2013  Object::Iterator itr = in_object.find(in_name);
2014  if ((itr == in_object.end()) || (*itr).getValue().isNull())
2015  return jsonReadError(
2016  JsonReadError::MISSING_MEMBER,
2017  "Member " + in_name + " does not exist in the specified JSON object.",
2018  ERROR_LOCATION);
2019 
2020  if (!(*itr).getValue().isArray())
2021  return jsonReadError(JsonReadError::INVALID_TYPE,
2022  "Member " + in_name + " is not an array.",
2023  ERROR_LOCATION);
2024 
2025  Array array = (*itr).getValue().getArray();
2026  for (size_t i = 0, n = array.getSize(); i < n; ++i)
2027  {
2028  const Value& value = array[i];
2029  if (!isType<T>(value))
2030  {
2031  std::ostringstream msgStream;
2032  msgStream << "Element " << i << " of member " + in_name << " is of type " << value.getType() <<
2033  " which is not compatible with the requested type " << typeid(T).name() << ".";
2034  return jsonReadError(
2035  JsonReadError::INVALID_TYPE,
2036  msgStream.str(),
2037  ERROR_LOCATION);
2038  }
2039 
2040  out_values.push_back(value.getValue<T>());
2041  }
2042 
2043  return Success();
2044 }
2045 
2057 template <typename T>
2058 Error readObject(const Object& in_object, const std::string& in_name, std::set<T>& out_values)
2059 {
2060  Object::Iterator itr = in_object.find(in_name);
2061  if ((itr == in_object.end()) || (*itr).getValue().isNull())
2062  return jsonReadError(
2063  JsonReadError::MISSING_MEMBER,
2064  "Member " + in_name + " does not exist in the specified JSON object.",
2065  ERROR_LOCATION);
2066 
2067  if (!(*itr).getValue().isArray())
2068  return jsonReadError(JsonReadError::INVALID_TYPE,
2069  "Member " + in_name + " is not an array.",
2070  ERROR_LOCATION);
2071 
2072  Array array = (*itr).getValue().getArray();
2073  for (size_t i = 0, n = array.getSize(); i < n; ++i)
2074  {
2075  const Value& value = array[i];
2076  if (!isType<T>(value))
2077  {
2078  std::ostringstream msgStream;
2079  msgStream << "Element " << i << " of member " + in_name << " is of type " << value.getType() <<
2080  " which is not compatible with the requested type " << typeid(T).name() << ".";
2081  return jsonReadError(
2082  JsonReadError::INVALID_TYPE,
2083  msgStream.str(),
2084  ERROR_LOCATION);
2085  }
2086 
2087  out_values.insert(value.getValue<T>());
2088  }
2089 
2090  return Success();
2091 }
2092 
2104 template <typename T>
2105 Error readObject(const Object& in_object, const std::string& in_name, Optional<std::vector<T> >& out_values)
2106 {
2107  std::vector<T> values;
2108  Error error = readObject(in_object, in_name, values);
2109  if (error && !isMissingMemberError(error))
2110  return error;
2111  else if (!error)
2112  out_values = values;
2113 
2114  return Success();
2115 }
2116 
2128 template <typename T>
2129 Error readObject(const Object& in_object, const std::string& in_name, Optional<std::set<T> >& out_values)
2130 {
2131  std::set<T> values;
2132  Error error = readObject(in_object, in_name, values);
2133  if (error && !isMissingMemberError(error))
2134  return error;
2135  else if (!error)
2136  out_values = values;
2137 
2138  return Success();
2139 }
2140 
2154 template <typename T, typename... Args>
2155 Error readObject(const Object& in_object, const std::string& in_name, T& out_value, Args&... io_args)
2156 {
2157  Error error = readObject(in_object, in_name, out_value);
2158  if (error)
2159  return error;
2160 
2161  return readObject(in_object, io_args...);
2162 }
2163 
2177 template <typename T, typename... Args>
2178 Error readObject(const Object& in_object, const std::string& in_name, Optional<T>& out_value, Args&... io_args)
2179 {
2180  Error error = readObject(in_object, in_name, out_value);
2181  if (error)
2182  return error;
2183 
2184  return readObject(in_object, io_args...);
2185 }
2186 
2201 template <typename T, typename... Args>
2202 Error readObject(const Object& in_object, const std::string& in_name, std::vector<T>& out_values, Args&... io_args)
2203 {
2204  Error error = readObject(in_object, in_name, out_values);
2205  if (error)
2206  return error;
2207 
2208  return readObject(in_object, io_args...);
2209 }
2210 
2225 template <typename T, typename... Args>
2226 Error readObject(const Object& in_object, const std::string& in_name, std::set<T>& out_values, Args&... io_args)
2227 {
2228  Error error = readObject(in_object, in_name, out_values);
2229  if (error)
2230  return error;
2231 
2232  return readObject(in_object, io_args...);
2233 }
2234 
2249 template <typename T, typename... Args>
2251  const Object& in_object,
2252  const std::string& in_name,
2253  Optional<std::vector<T> >& out_value,
2254  Args&... io_args)
2255 {
2256  Error error = readObject(in_object, in_name, out_value);
2257  if (error)
2258  return error;
2259 
2260  return readObject(in_object, io_args...);
2261 }
2262 
2277 template <typename T, typename... Args>
2279  const Object& in_object,
2280  const std::string& in_name,
2281  Optional<std::set<T> >& out_value,
2282  Args&... io_args)
2283 {
2284  Error error = readObject(in_object, in_name, out_value);
2285  if (error)
2286  return error;
2287 
2288  return readObject(in_object, io_args...);
2289 }
2290 
2291 } // namespace json
2292 } // namespace launcher_plugins
2293 } // namespace rstudio
2294 
2295 #endif // LAUNCHER_PLUGINS_JSON_HPP
2296 
rstudio::launcher_plugins::json::Object::ReverseIterator
std::reverse_iterator< Iterator > ReverseIterator
Reverse iterator for a JSON object.
Definition: Json.hpp:833
rstudio::launcher_plugins::json::Object::Member::getValue
Value getValue() const
Gets the value of the member.
rstudio::launcher_plugins::json::Value::getUInt64
uint64_t getUInt64() const
Gets the value as an uint64. If the call to getType() does not return Type::UINT64,...
rstudio::launcher_plugins::json::Value::clone
Value clone() const
Makes a copy of this JSON value.
rstudio::launcher_plugins::json::Object::isEmpty
bool isEmpty() const
Checks whether the JSON object is empty.
rstudio::launcher_plugins::json::Object::Iterator::operator=
Iterator & operator=(const Iterator &in_other)
Assignment operator.
rstudio::launcher_plugins::json::Value::parse
virtual Error parse(const char *in_jsonStr)
Parses the JSON string into this value.
rstudio::launcher_plugins::json::Array::Iterator::operator==
bool operator==(const Iterator &in_other) const
Equality operator.
rstudio::launcher_plugins::json::Object
Class which represents a specific type of JSON Value: a JSON object.
Definition: Json.hpp:687
rstudio::launcher_plugins::json::Array::getFront
Value getFront() const
Gets the value at the front of the JSON array.
rstudio::launcher_plugins::json::Object::rend
ReverseIterator rend() const
Gets an iterator before the first member of this object, which can be compared with an other ReverseI...
rstudio::launcher_plugins::ErrorLocation
Class which represents the location of an error.
Definition: Error.hpp:74
rstudio::launcher_plugins::json::Value::getInt64
int64_t getInt64() const
Gets the value as an int64. If the call to getType() does not return Type::INT64, this method is inva...
rstudio::launcher_plugins::json::Value::isObject
bool isObject() const
Checks whether the value is a JSON object or not.
rstudio::launcher_plugins::json::Value::isUInt64
bool isUInt64() const
Checks whether the value is an unsigned int 64 value or not.
rstudio::launcher_plugins::json::Value::~Value
virtual ~Value()=default
Virtual destructor.
rstudio::launcher_plugins::json::Value::getBool
bool getBool() const
Gets the value as a bool. If the call to getType() does not return Type::BOOL, this method is invalid...
rstudio::launcher_plugins::json::Object::operator=
Object & operator=(const Object &in_other)
Assignment operator.
rstudio::launcher_plugins::json::toJsonArray
Array toJsonArray(const std::vector< T > &in_vector)
Converts a vector value to a JSON array value.
Definition: Json.hpp:1878
rstudio::launcher_plugins::json::Value::getInt
int getInt() const
Gets the value as an int. If the call to getType() does not return Type::INT, this method is invalid.
rstudio::launcher_plugins::json::Array::Iterator
Class which allows iterating over the elements of a JSON array.
Definition: Json.hpp:1222
rstudio::launcher_plugins::json::Array::clear
void clear()
Clears the JSON array.
rstudio::launcher_plugins::json::Value::Value
Value()
Constructor.
rstudio::launcher_plugins::json::Array::getValueAt
Value getValueAt(size_t in_index) const
Gets the value at the specified index of the JSON array.
rstudio::launcher_plugins::json::isType
bool isType(const Value &in_value)
Checks whether the specified JSON value is of the type specified in the template parameter.
Definition: Json.hpp:1664
rstudio::launcher_plugins::json::Array::value_type
Value value_type
Typedef required for the inheritance of std::iterator with a value_type of json::Value.
Definition: Json.hpp:1217
rstudio::launcher_plugins::json::Object::clear
void clear()
Clears the JSON object.
rstudio::launcher_plugins::json::Array::Iterator::operator!=
bool operator!=(const Iterator &in_other) const
Inequality operator.
rstudio::launcher_plugins::json::Value::getArray
Array getArray() const
Gets the value as a JSON array. If the call to getType() does not return Type::ARRAY,...
rstudio::launcher_plugins::json::jsonReadError
Error jsonReadError(JsonReadError in_errorCode, const std::string &in_message, const ErrorLocation &in_errorLocation)
Creates a JSON read error.
rstudio::launcher_plugins::json::Object::erase
bool erase(const char *in_name)
Erases a member by name.
rstudio::launcher_plugins::json::Array::toStringPairList
StringPairList toStringPairList() const
Converts this array into a vector of string pairs. Elements of the form "key=value" will be parsed in...
rstudio::launcher_plugins::json::Object::operator[]
Value operator[](const char *in_name)
Accessor operator. Gets the value a member of this JSON object by name. If no such object exists,...
rstudio::launcher_plugins::json::Value::isString
bool isString() const
Checks whether the value is a string value or not.
rstudio::launcher_plugins::json::Value::getDouble
double getDouble() const
Gets the value as a double. If the call to getType() does not return Type::DOUBLE,...
rstudio::launcher_plugins::json::Value::isArray
bool isArray() const
Checks whether the value is a JSON array or not.
rstudio::launcher_plugins::json::Object::toStringMap
bool toStringMap(StringListMap &out_map) const
Converts this JSON object to a map with string keys and a list of string values.
rstudio::launcher_plugins::json::Object::getSize
size_t getSize() const
Gets the number of members in the JSON object.
rstudio::launcher_plugins::json::Array::erase
Iterator erase(const Iterator &in_itr)
Erases the member specified by the provided iterator.
rstudio::launcher_plugins::json::Object::Iterator::Iterator
Iterator(const Object *in_parent, std::ptrdiff_t in_startPos=0)
Constructor.
rstudio::launcher_plugins::json::Array::operator[]
Value operator[](size_t in_index) const
Accessor operator. Gets the JSON value at the specified position in the array.
rstudio::launcher_plugins::json::Object::Iterator::operator==
bool operator==(const Iterator &in_other) const
Equality operator.
rstudio::launcher_plugins::json::Array::operator=
Array & operator=(const Array &in_other)
Assignment operator.
rstudio::launcher_plugins::json::Value::operator=
Value & operator=(const Value &in_other)
Assignment operator from Value.
rstudio::launcher_plugins::json::Object::Iterator::operator!=
bool operator!=(const Iterator &in_other) const
Inequality operator.
rstudio::launcher_plugins::json::Array::getSize
size_t getSize() const
Gets the number of values in the JSON array.
rstudio::launcher_plugins::json::Array::Iterator::Iterator
Iterator(const Array *in_parent, std::ptrdiff_t in_startPos=0)
Constructor.
rstudio::launcher_plugins::json::Object::end
Iterator end() const
Gets an iterator after the last member of this object.
rstudio::launcher_plugins::Success
Class which represents a successful operation (i.e. no error).
Definition: Error.hpp:437
rstudio::launcher_plugins::json::readObject
Error readObject(const Object &in_object, const std::string &in_name, T &out_value)
Reads a member from an object.
Definition: Json.hpp:1941
rstudio::launcher_plugins::json::Value::PRIVATE_IMPL_SHARED
PRIVATE_IMPL_SHARED(m_impl)
Private implementation of Value.
rstudio::launcher_plugins::json::Array::push_back
void push_back(const Value &in_value)
Pushes the value onto the end of the JSON array.
rstudio::launcher_plugins::json::Array::Array
Array()
Constructs an empty JSON array.
rstudio::launcher_plugins::json::Value::validate
Error validate(const std::string &in_schema) const
Validates this JSON value against a schema.
rstudio::launcher_plugins::json::Value::operator!=
bool operator!=(const Value &in_other) const
Inequality operator.
rstudio::launcher_plugins::json::Array::Iterator::operator--
Iterator & operator--()
Pre-decrement operator.
rstudio::launcher_plugins::json::Object::Iterator::operator*
reference operator*() const
Dereference operator.
rstudio::launcher_plugins::json::detail::asJsonType
Type asJsonType(const T &in_object, std::true_type)
Internal utility function. Gets the type of the object as a JSON type, if the object is a JSON type (...
Definition: Json.hpp:1718
rstudio::launcher_plugins::json::Array::Iterator::operator=
Iterator & operator=(const Iterator &in_other)
Assignment operator.
rstudio::launcher_plugins::json::Value::getUInt
unsigned int getUInt() const
Gets the value as an unsigned int. If the call to getType() does not return Type::UINT,...
rstudio::launcher_plugins::json::Value::setValueAtPointerPath
Error setValueAtPointerPath(const std::string &in_pointerPath, const json::Value &in_value)
Sets a value within the current value based on the specified JSON Pointer path.
rstudio::launcher_plugins::json::Value::isFloat
bool isFloat() const
Checks whether the value is a float value or not.
rstudio::launcher_plugins::json::Value::getObject
Object getObject() const
Gets the value as a JSON object. IF the call to getType() does not return Type::OBJECT,...
rstudio::launcher_plugins::json::Value::isInt
bool isInt() const
Checks whether the value is an int 32 value or not.
rstudio::launcher_plugins::json::Value::isInt64
bool isInt64() const
Checks whether the value is an int 64 value or not.
rstudio::launcher_plugins::json::isMissingMemberError
bool isMissingMemberError(const Error &in_error)
Checks whether the supplied error is a "missing member" error.
rstudio::launcher_plugins::json::Array::parse
Error parse(const char *in_jsonStr) override
Parses the JSON string into this array.
rstudio::launcher_plugins::json::Object::Iterator
Class which allows iterating over the members of a JSON object.
Definition: Json.hpp:734
rstudio::launcher_plugins::json::Object::begin
Iterator begin() const
Gets an iterator pointing to the first member of this object.
rstudio::launcher_plugins::json::Array::Iterator::operator++
Iterator & operator++()
Pre-increment operator.
rstudio::launcher_plugins::json::Object::rbegin
ReverseIterator rbegin() const
Gets an iterator pointing to the last member of this object, which iterates in the reverse direction.
rstudio::launcher_plugins::json::Object::find
Iterator find(const char *in_name) const
Finds a JSON member by name.
rstudio::launcher_plugins::json::Array::toSetString
bool toSetString(std::set< std::string > &out_set) const
Converts this JSON array to a set of strings.
rstudio::launcher_plugins::json::Array::ReverseIterator
std::reverse_iterator< Iterator > ReverseIterator
Reverse iterator for a JSON array.
Definition: Json.hpp:1320
rstudio::launcher_plugins::json::detail::toJsonValue
Value toJsonValue(const T &in_value)
Internal utility function. Converts a C/C++ value to a JSON value.
Definition: Json.hpp:1760
rstudio::launcher_plugins::Error
Class which represents an error.
Definition: Error.hpp:174
rstudio::launcher_plugins::json::Type
Type
Enum which represents the type of a json value.
Definition: Json.hpp:59
rstudio::launcher_plugins::json::Value::getString
std::string getString() const
Gets the value as a string. If the call to getType() does not return Type::STRING,...
rstudio::launcher_plugins::json::Array::begin
Iterator begin() const
Gets an iterator pointing to the first member of this array.
Logger.hpp
rstudio::launcher_plugins::json::Array::getBack
Value getBack() const
Gets the value at the back of the JSON array.
rstudio::launcher_plugins::json::Value::getValue
T getValue() const
Gets this JSON value as the specified type.
rstudio::launcher_plugins::json::Array::toVectorInt
bool toVectorInt(std::vector< int > &out_set) const
Converts this JSON array to a vector of integers.
rstudio::launcher_plugins::json::Array
Class which represents a JSON array.
Definition: Json.hpp:1210
rstudio::launcher_plugins::json::Array::isEmpty
bool isEmpty() const
Checks whether the JSON array is empty.
rstudio::launcher_plugins::json::Array::toVectorString
bool toVectorString(std::vector< std::string > &out_set) const
Converts this JSON array to a vector of strings.
rstudio::launcher_plugins::json::Array::rbegin
ReverseIterator rbegin() const
Gets an iterator pointing to the last member of this array, which iterates in the reverse direction.
rstudio::launcher_plugins::json::Value::isDouble
bool isDouble() const
Checks whether the value is a double value or not.
rstudio::launcher_plugins::json::Value::parseAndValidate
Error parseAndValidate(const std::string &in_jsonStr, const std::string &in_schema)
Parses the JSON string and validates it against the schema.
rstudio::launcher_plugins::Optional
Container class which represents a value that may or may not be set.
Definition: Optional.hpp:38
rstudio::launcher_plugins::json::Value::isNull
bool isNull() const
Checks whether the value is null or not.
rstudio::launcher_plugins::json::Object::insert
void insert(const std::string &in_name, const Value &in_value)
Inserts the specified member into this JSON object. If an object with the same name already exists,...
rstudio::launcher_plugins::json::Value::write
std::string write() const
Writes this value to a string.
rstudio::launcher_plugins::json::Value::getFloat
float getFloat() const
Gets the value as a float. If the call to getType() does not return Type::FLOAT, this method is inval...
rstudio::launcher_plugins::json::detail::is_json_type
Struct which is either a child class of std::true_type or std::false_type depending on whether T is a...
Definition: Json.hpp:1704
rstudio::launcher_plugins::json::Value::getType
Type getType() const
Gets the type of this value.
rstudio::launcher_plugins::json::Object::getSchemaDefaults
static Error getSchemaDefaults(const std::string &in_schema, Object &out_schemaDefaults)
Creates a JSON object which represents the schema defaults of the provided JSON schema string.
rstudio::launcher_plugins::json::Object::hasMember
bool hasMember(const char *in_name) const
Checks whether this object has a member with the specified name.
rstudio::launcher_plugins::json::Value::coerce
Error coerce(const std::string &in_schema, std::vector< std::string > &out_propViolations)
Attempts to coerce a JSON object to conform to the given schema by discarding non-conforming properti...
rstudio::launcher_plugins::json::Object::Member::Member
Member()=default
Default constructor.
rstudio::launcher_plugins::json::Object::createMember
static Member createMember(const std::string &in_name, const Value &in_value)
Creates a JSON object from the given name and JSON value.
rstudio::launcher_plugins::json::Value::ValueImplPtr
std::shared_ptr< Impl > ValueImplPtr
Convenience typedef for the type of the private implementation of json::Value.
Definition: Json.hpp:86
rstudio::launcher_plugins::json::Array::end
Iterator end() const
Gets an iterator after the last member of this array.
rstudio::launcher_plugins::json::Object::Iterator::operator--
Iterator & operator--()
Pre-decrement operator.
rstudio::launcher_plugins::json::Value::isBool
bool isBool() const
Checks whether the value is a boolean value or not.
rstudio::launcher_plugins::json::Object::Member
Class which represents a single member of a JSON object.
Definition: Json.hpp:695
rstudio::launcher_plugins::json::Object::Object
Object()
Constructs an empty JSON object.
rstudio::launcher_plugins::json::Object::mergeObjects
static Object mergeObjects(const Object &in_base, const Object &in_overlay)
Merges two JSON objects together. Conflicts between the base and the overlay will be resolved by taki...
rstudio::launcher_plugins::json::Object::Iterator::operator++
Iterator & operator++()
Pre-increment operator.
rstudio::launcher_plugins::json::Array::rend
ReverseIterator rend() const
Gets an iterator before the first member of this array, which can be compared with an other ReverseIt...
rstudio::launcher_plugins::json::Object::toStringPairList
StringPairList toStringPairList() const
Converts this JSON object to a list of string pairs.
rstudio::launcher_plugins::json::Value::writeFormatted
std::string writeFormatted() const
Writes and formats this value to a string.
rstudio::launcher_plugins::json::JsonReadError
JsonReadError
Errors which may occur while reading values from JSON objects.
Definition: Json.hpp:1902
rstudio::launcher_plugins::json::Value::isUInt
bool isUInt() const
Checks whether the value is an unsigned int 32 value or not.
rstudio::launcher_plugins::json::Object::parse
Error parse(const char *in_jsonStr) override
Parses the JSON string into this object.
rstudio::launcher_plugins::json::Value
Class which represents a json value.
Definition: Json.hpp:74
rstudio::launcher_plugins::json::Array::Iterator::operator*
reference operator*() const
Dereference operator.
rstudio::launcher_plugins::json::Value::operator==
bool operator==(const Value &in_other) const
Equality operator.
rstudio::launcher_plugins::json::Object::Member::getName
const std::string & getName() const
Gets the name of the member.